Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

Avoid the Gates of Hell. Use Linux -- unknown source


computers / comp.arch / Re: Minor idea for indirect target predictor

Re: Minor idea for indirect target predictor

<sc7k6n$3a3$1@dont-email.me>

  copy mid

https://www.novabbs.com/computers/article-flat.php?id=18522&group=comp.arch#18522

  copy link   Newsgroups: comp.arch
Path: i2pn2.org!i2pn.org!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: cr88...@gmail.com (BGB)
Newsgroups: comp.arch
Subject: Re: Minor idea for indirect target predictor
Date: Thu, 8 Jul 2021 14:34:25 -0500
Organization: A noiseless patient Spider
Lines: 743
Message-ID: <sc7k6n$3a3$1@dont-email.me>
References: <sbrv45$d0s$1@gioia.aioe.org> <sbsqiq$2mv$1@dont-email.me>
<sbsrmv$7rm$1@newsreader4.netcologne.de> <sbt9lt$bsb$1@dont-email.me>
<sbtaqn$iia$1@newsreader4.netcologne.de>
<162544050840.32204.2008019713843981060@media.vsta.org>
<sbtglg$le4$1@dont-email.me> <sbu3je$3ad$1@newsreader4.netcologne.de>
<sbvgsb$hvc$1@dont-email.me> <sc3s8o$a97$1@dont-email.me>
<sc4v50$dqc$1@dont-email.me> <sc6ig0$img$1@dont-email.me>
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit
Injection-Date: Thu, 8 Jul 2021 19:37:59 -0000 (UTC)
Injection-Info: reader02.eternal-september.org; posting-host="530192340c5dcd343d59f73c750a8cd6";
logging-data="3395"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/Ne5v/0OUcK6VF/4p9kgZU"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101
Thunderbird/78.11.0
Cancel-Lock: sha1:MbPG3R2Dw92uOyqUzOJjzt7kesE=
In-Reply-To: <sc6ig0$img$1@dont-email.me>
Content-Language: en-US
 by: BGB - Thu, 8 Jul 2021 19:34 UTC

On 7/8/2021 5:02 AM, David Brown wrote:
> On 07/07/2021 21:22, BGB wrote:
>> On 7/7/2021 4:31 AM, David Brown wrote:
>>> On 05/07/2021 19:49, BGB wrote:
>>>> On 7/4/2021 11:59 PM, Thomas Koenig wrote:
>>>>> Ivan Godard <ivan@millcomputing.com> schrieb:
>>>>>
>>>>>> Prolog is the perfect tool for Prolog-shaped problems. As is Snobol
>>>>>> for
>>>>>> the Snobol-shaped.
>>>>>
>>>>> Some people who don't like C++ say that C++ is the perfect tool
>>>>> for thumb-shaped problems :-)
>>>>>
>>>>
>>>> Main problems I have with C++ ATM:
>>>>    Compiler would be too complicated, don't want to bother with this;
>>>
>>> C++ compilers are certainly complicated.  It's a big language, and it is
>>> a demanding language for compilers.  Parsing is hard, with lots of
>>> conditional keywords, and you need to be happy with heavy inlining or
>>> the results will be hopelessly inefficient.
>>>
>>
>> Yeah.
>>
>> There are reasons why I have not been making more effort to try to add
>> C++ support to BGBCC. I can support a limited subset, but going much
>> beyond this would be an uphill battle.
>>
>>
>> I am generally working though towards at least trying to support C
>> effectively. Programs generally work, though there are corner cases
>> which still aren't supported effectively.
>>
>
> For a one-person toolchain, C is more than big enough!
>
>>
>> Eg, recently I had a few bugs which were being an issue and leading to a
>> program having different behavior in BGBCC vs GCC or Clang.
>>
>> Eventually, I found a few bugs, among them was things like:
>>   j = 9999U / i;
>> Where 'i' and 'j' are 'int'.
>>
>> Where the former value would lose its unsigned status resulting in the
>> expression being evaluated as 'int' rather than 'unsigned int', which
>> would lead to different behavior if 'i' was negative.
>>
>>
>
> The rules for implicit conversions and integer promotions are clear
> enough in C - it shouldn't be hard to support them correctly. (I don't
> entirely agree with the choices for the rules, but that's another matter.)
>

This was due to a compiler bug.

In some paths, it checked that it was dealing with an integer immediate,
but failed to check that it was dealing with an 'unsigned' integer
immediate...

>
>>
>>>>    Multiple inheritance needlessly complicates stuff;
>>>
>>> I'm not a fan of multiple inheritance myself.  In particular, inheriting
>>> data from different places is likely to cause trouble, and multiple
>>> inheritance of classes with virtual methods is very rarely worth the
>>> complication and confusion.  CRTP, however, can be really neat (for
>>> compile-time polymorphism).  In one project I am working on, I have
>>> templates for GPIO pins, arranged with inheritance:
>>>
>>> template <int gpio_bank, int gpio_pin, bool output = false>
>>> class GpioInOut :
>>>     public GpioIn<gpio_bank, gpio_pin>,
>>>     public GpioOut<gpio_bank, gpio_pin>
>>> ...
>>>
>>> It works neatly, the source code is clear, it is hard to use incorrectly
>>> as you can't mix up pins or accidentally drive an input-only pin, and
>>> the resulting code is as efficient as possible since the compiler has
>>> all the details of pin numbers, addresses, etc., on hand when compiling
>>> "green_led.on();".
>>>
>>> Multiple inheritance is a powerful tool, and is often used very poorly -
>>> but it /can/ be used very well.
>>>
>>
>> OK.
>>
>>
>>>>    Templates needlessly complicate stuff;
>>>
>>> Templates change the nature of the language significantly.  If you still
>>> think of C as being a language where a function in the source code
>>> corresponds precisely to a function in the generated assembly, and you
>>> think of C++ as being like C with extra features, you will not be able
>>> to handle templates.  Of course, it is a long time (perhaps three
>>> decades) since C has had complete correspondence in functions - but
>>> often you can pretend it works that way when it is useful.
>>>
>>
>> Yeah. I am primarily a C programmer.
>>
>> Generally this is because either the extra features C++ had added were
>> not sufficiently compelling, or because something else created
>> roadblocks that made it effectively unusable (or put constraints on it
>> that rendered it effectively moot).
>>
>
> There are times when C is a better choice - being simpler, more
> explicit, and easier to follow can help. Other times C++ makes it
> easier to express what you want, and lets you write code that is safer
> and easier to follow. (And of course, almost any reasonable C code will
> have the same meaning in C++, with at most minor adjustments.)
>

Generally true.

Except when for whatever reason C++ is not usable, eg:
No compiler for the target;
Compiler for the target is otherwise non-functional;
One is dealing with FFI tools which only understand C;
...

Variations on these patterns occurring repeatedly have basically meant
that for me, C++ had generally been "less safe" than C, since there were
fewer contexts I could use the code in.

Ironically, this also limits use of my own languages to some extent,
since it means that most code written in them is essentially ephemeral
(usually, tied to a specific project). This is OK for high-level glue
logic, not so much for other things.

>>
>>> In C++, however, the move has been towards higher level coding.
>>> Templates generate functions and classes.  They let you write more
>>> general code, with a lot more flexibility.
>>>
>>> Again, templates are powerful and can be abused, and template coding can
>>> certainly be complicated.  (It's got much easier in newer C++
>>> standards.)  But to suggest they are "needless" is tantamount to
>>> admitting you really do not understand the language at all.
>>>
>>
>> I understand a subset of C++, namely the subset where one treats it
>> mostly like C with classes, namespaces, and operator overloading...
>>
>
> You can get far with a subset like that. I'd throw references (lvalue
> references, not rvalue references), better const, and scoped enums into
> that mix as features that are quite simple to understand and where their
> functionality and implementation is obvious.
>

Yeah, some of these are also useful.

> (And you might want to disable exceptions and RTTI - it is standard
> practice on small embedded systems and also in game programming.)
>

My feeling on these are mixed, both can be useful.

My main issue with exceptions though is people trying to use them for
general control flow rather than for "edge case where something has gone
seriously wrong".

>>
>> Though, one can note that much of the language as it exists in its
>> present form depends on templates, and if one omits them it mostly
>> reverts back to a more C-like subset.
>>
>
> A lot of features of C++ can be viewed as things you need to /make/ the
> libraries or frameworks, rather than what you need to /use/ them. For
> example, in any situation where in C you would use an array with a size
> that is known at compile time, you can use a std::array from C++ to get
> some extra features and type-safety with no overhead. You don't have to
> be able to write such template classes in order to use them.
>

OK.

>>
>> There was EC++, which was also such a subset, however EC++ was actually
>> more limited than I would aim for.
>>
>> For example, I consider the added complexity of namespaces to be
>> justifiable (since it has something to offer, and is one of the few C++
>> features which delivers on the promise of not having any runtime
>> performance impact).
>>
>
> Most features of C++ have zero or close to zero overhead - compared to
> alternative solutions. For example, virtual functions in C++ have
> run-time costs, but they are likely to be lower than a C-style system of
> pointers to tables of function pointers doing the same thing.
>

The underlying implementation tends to be virtually the same, so it
shouldn't make that much difference.

> Real-world comparisons between C and C++ suggest the overhead of C++ is
> in the region of a percent or two - with plenty of variation depending
> on the type of code. (C++ object files will often be very much bigger
> when linking and debug information is still there, and exception tables
> can take up a lot of space in binaries in some cases.)
>

Yeah. In my case the exception unwind tables use a trick of reusing a
pointer to the epilog sequence to implement unwinding. The unwind logic
needs to be able to parse machine code, but it allows reducing the
amount of space overhead.

>>
>>>>    The C++ standard library and STL is kinda a trash fire;
>>>
>>> There is plenty to like, and plenty to dislike in the C++ standard
>>> library.  It contains a great deal of functionality that few people will
>>> ever need, and that does complicate things.  And it suffers from
>>> backwards compatibility (as does the language) - once something is in
>>> the language, or the library, it is hard to remove it even if better
>>> methods have been found.
>>>
>>
>> Some of it was older stuff that seemed more like "language feature in
>> search of a use-case" than because of it making sense to do it that way.
>>
>>
>> Eg: overloading operators to add new types and make them behave kinda
>> like built-in types, makes sense. Overloading operators for sake of
>> doing File IO or formatted printing, ..., yeah...
>
> I think the cout-style output is a mixed blessing. It is convenient in
> some ways, but fails in others. It is vastly superior to printf in type
> safety and flexibility in defining output formats for your own types.
> It is vastly inferior for translating format strings, and for modifying
> the format of number outputs.
>

There are limitations with printf, granted.

Some are more due to C's particularly weak way of handling variable
argument lists than due to the general design of its interface though.

>>
>> It is possibly telling that two of its major 'successors' (Java and C#),
>> either eventually or initially, mostly went back to doing it in a
>> similar way to C.
>>
>
> (There is a new system of formatted output on its way to the C++ library.)
>

If it is essentially a rebranded "printf", that would be amusing...

But, as noted, since the standard C++ library mostly consists of:
Stuff from the C library, just slightly repackaged;
A lot of stuff that is, a bit, questionable;
Stuff that builds on templates;
...

I am prone to mostly ignore its existence.

There are OK parts, like "std::string" seems "not awful", ...

>>
>>>>    ...
>>>>
>>>> Too many "features" exist essentially as a way to play whack-a-mole with
>>>> the consequences of other features.
>>>> If you leave out multiple inheritance and templates, many of the rest of
>>>> the language features go "poof" and disappear.
>>>>
>>>
>>> If you leave out templates, the /language/ goes "poof" and disappears.
>>> All you are left with is C with better structuring and a bit more type
>>> safety - and you are back to copy-and-paste and macros for anything
>>> generic.
>>>
>>
>> Well, whether it is most of the language features going poof and
>> disappearing, or the whole language going poof and disappearing, is a
>> possible subject of interpretation.
>>
>>
>>> It's like saying FORTRAN would be simpler without arrays.
>>>
>>> (There was an attempt at a C++ subset that simplified and restricted the
>>> language, aimed as resource-limited systems - "Embedded C++".  It was a
>>> total and utter failure, and no one used it.)
>>>
>>
>> I am aware of it.
>>
>> Ironically, BGBCC can more or less compile EC++ code, though that
>> doesn't mean that much mainline C++ code will work with it.
>>
>> Partly this is because EC++ also happens to mostly fall within the
>> "common superset" of features which contains both C and BS2...
>>
>>
>> My compiler also allows using some amount of BS2 features from C (as an
>> extension), but this does lead to some things being a little uglier.
>>
>> For example, in BS2 one could write something like:
>>   var obj = {x: 3, y: 4};
>> Whereas, I am still on the fence of whether to allow something like:
>>   __variant obj = (__variant) { .x=3, .y=4 };
>>
>> At present, one has to do it more like:
>>   __variant obj;
>>   obj = __lvo_emptyobject();
>>   obj.x = 3;  //assigning a non-existing field in a tag-obj creates it.
>>   obj.y = 4;
>>
>> Where '__lvo_emptyobject()' is essentially the runtime support function
>> behind the '{}' expression (as in, "var obj = {};").
>>
>> Granted, I don't expect this stuff to be widely used in C land (nor
>> should it be), so there probably isn't much need to make it "not ugly".
>>
>> A lot of stuff is still pretty incomplete in this implementation though,
>> partly as I hadn't been putting much effort into getting everything
>> implemented. Perhaps unsurprisingly, 'variant' will also have a higher
>> runtime performance cost relative to the use of native types (given it
>> is mostly implemented via runtime calls operating on tagged pointers).
>>
>> Theoretically, in theory, the same runtime support could be used for
>> other "JavaScript family" languages, such as JS, AS3, or Haxe. Though,
>> there is a fair bit of variability within the JS family.
>>
>>
>>>>
>>>> Leaving out templates also eliminates on of the major sources of massive
>>>> code bloat and excessive build times.
>>>>
>>>
>>> Misuse of templates can lead to code bloat, especially with poorer
>>> compilers.  Good use of templates makes code smaller as the generality
>>> is handled
>>>
>>
>> I have usually seen code get bigger.
>>
>>
>> There are possible ways to combat expansion, in theory, but I am not
>> sure if they are really allowed or commonly done.
>
> The most obvious way is that a lot of template functions are quite
> small, and thus end up inlined saving space (no function call, no
> register movements, saves and restores, more scope for other optimisations).
>

Not ideal if the compiler lacks support for inlining...

> Toolchains also work to de-duplicate the code. I know that with gcc and
> binutils, this can be done on several levels. Code that has the same
> RTL representation gets de-duplicated by the compiler (i.e., multiple
> template function instantiations that boil down to the same code). Code
> that ends up as a function will be de-duplicated by the linker if the
> same function name (template, types, overloading, etc.) turns up from a
> different compilation unit. And the linker can, at least to some
> extent, de-duplicate code sequences that happen to match exactly.
>

Yeah, errm, BGBCC doesn't do this either...

>>
>> One example would be to limit template expansions by falling back to
>> tagged pointers if an excessive number of templates have been
>> instantiated. Possible issues are mostly that it could expose problems
>> if the semantics differ, or due to the added overheads of using dynamic
>> type-checking and/or dynamic dispatch (it it happens to be on a hot path).
>>
>
> You mean that instead of generating code for foo(U) and foo(V), the
> compiler could generate code for foo(std::variant<U, V> *) ? That
> would IMHO be a terrible idea. If the programmer wants run-time
> polymorphism, C++ supports that - it's called class inheritance and
> virtual functions. A toolchain should not just decide to save some
> space at compile-time by moving these decisions to run time! (And if
> using a variant here would be the best choice, C++ supports that too -
> /if/ the programmer chooses it.)
>

Not for std::variant, but for a proper dynamic type (more like one might
find in something like JavaScript or Python or similar).

But, in this case, the idea is to reduce the space overhead in extreme
cases by merging most of the expansion (past a certain cutoff point)
into a slower dynamically-typed path.

In this case, it offloads most of the type handling to the language runtime.

>>
>> One issue is that the C++ typesystem is too complicated to be captured
>> accurately within a viable tagged-pointer system, so this can't be made
>> entirely transparent.
>>
>
> It should not be made at all.
>
> If you want dynamic languages with duck-typing and the rest, those are
> available too.
>

Granted, but this is what I am working with in this case...

I have a C compiler that is distantly descended from an interpreter I
did for a JavaScript / ECMAScript3 clone, which is not a C/C++ compiler,
but a semi-conjoined compiler for C and a descendant of said JS-clone.

It gets dynamic (or "duck") typing, because that is what its ancestor used.

But, as noted, in the BGBScript 1.5 / 2.0 model, the original dynamic
typesystem was folded off into a type known as "variant", which was in
turn named after the type in VisualBasic.

In this case, most of the core of the language is statically typed, but
a restricted shadow of the main static type-system may exist in terms of
the dynamic type system.

Some types may be boxed, for example:
Int128 or Float128 can be expressed directly in the static type-system,
but may end up being boxed types if cast to variant (though, there are
some vestigial placeholders in the typesystem for a 128-bit "fat variant").

But, noted, the BS2/BGBCC typesystem is roughly organized as roughly:
* SmallInt
** byte, sbyte, ubyte, bool, cchar
** short, ushort, char
** int, uint
* SmallLong
** long, ulong
** SmallInt(all)
* SmallInt128
** int128, uint128
** SmallLong(all)
* SmallFloat
** float
** float16 (exposed as "short float" in C)
* SmallDouble
** double
** SmallFloat
* SmallFloat128
** float128
** "long double"
** SmallDouble
* SmallFComplex
** "_Complex float" / "fcomplex"
** SmallFloat
* SmallDComplex
** "_Complex double" / "dcomplex"
** SmallDouble
* SmallQuat
** QuatF / 'quatf' (quaternion math)
** SmallFComplex
* M64
** Vec4H
** Vec2F
** FComplex
** ...
* M128
** Vec4F
** QuatF
** DComplex
* Pointers
** Pointers to any of the above.
** Reference Variables
* Variant / TagRef
** Fixnum (62-bit, signed)
** Flonum (62-bit)
** TagPointer
*** TagObject
*** TagArray
*** ClassObj
**** ( Single Inheritance, Static Layout, Interfaces )
** ...

Int128 ended up being the largest native integer type in both BS2 and in
BGBCC. On BJX2, this type has partial support in hardware.

Float128, largest floating point type, full precision in hardware is
impractical on an FPGA. Handling "long double" as a truncated subset had
been experimented with (essentially a Float96 with 80 bit mantissa), but
runs into the drawback of still being quite expensive.

As noted, objects split off into several directions:
* C structs
** C++ 'class' treated as a special case of C struct.
* BS2 ClassObj
* TagObject

Where, TagObject implements a dynamic Key/Value mapping (essentially a
dictionary mapping containing variants), with symbols mapped to 16-bit
integers (with 64-bits for payload for each field).

This implements something analogous to the more traditional JavaScript
style objects, but with a few restrictions:
* Objects and Arrays are separate;
* Objects may only be accessed by field name.
** They are not an open-ended associative set.
** They don't allow for overloaded methods.
** ...

ClassObj has a fixed layout:
* VTable Pointer
** Data Region
** Interface VTable Pointers

With the layout being append-only (each subclass appends any new fields
or Interface VTable pointers onto the end of the existing class layout).

Generally the VTables have the first 4 entries being reserved, typically
a pointer to the ClassInfo structure, and a displacement from the base
object (for interfaces). Calling a method generally involves taking the
object pointer and subtracting the vtable's displacement value to get
the "this" for the called method.

Casting a class to an implemented interface generally consists of adding
the displacement to the interface vtable pointer (known at compile time).

There is another case known as a "dynamic class":
public dynamic class Foo { ... }

Which behaves like a class object but allows new fields to be added at
run-time.

In this case, it consists of a ClassObj with an internal pointer to a
TagObj structure (not necessarily at a fixed location, but its offset is
given in the ClassInfo structure).

Note that, with ClassObj's, the ClassInfo structure is the main way of
identifying the object or interface types (conceptually, they are
identified via QName).

TagArrays are basically an array with an object header glued on (VTable
pointer, size, ...), and are used as either statically or dynamically
typed arrays, and are nominally 1D only (can fake 2D via nesting). These
are typically also heap-allocated.

Note that the BGBScript 1.5 language relied more heavily on
type-inference (and was syntactically more like ActionScript3 and Haxe),
whereas for 2.0 I moved over to a more Java style syntax (with some
elements borrowed from C#). Partly, this move was also because the
original BS typesystem and scope model had become "kinda evil" (and the
2.0 design was essentially a soft-reboot intended to bring the compiler
more within the realm of sanity).

The syntax change was more a mix of aesthetic preference, and because it
made cross-language copy/paste less of a hassle.

Note that these were via their own VM's, the implementation within BGBCC
is effectively another re-implementation of BS2.

Partly this is also because native-compiling is a lot more viable than
trying to run a full-featured VM framework or interpreter on BJX2. But,
in some ways, native compilation is a little harder for a language like
this.

>> This might manifest in terms of losing some type distinctions which are
>> otherwise necessary for the correct behavior of the program.
>>
>> These would include distinctions between, say:
>> Integer types which may be lost if they are converted to a generic
>> "fixnum" type (eg: type-size or signed/unsigned distinctiveness);
>> Cases where the type associated with an underlying memory allocation
>> either isn't known or differs from the type pointed to by the pointer;
>> Cases where a class is allocated as an instance of one type, but then
>> cast and used via a pointer to another type;
>> ...
>>
>>
>> This approach does work better with JavaScript family languages, given
>> that typically the typesystem can be more constrained and the static
>> typesystem (to what extent it exists) can be fully expressed within the
>> dynamic typesystem.
>>
>>
>> In a language with a hybrid type-system, one can constrain it to a
>> subset which is valid in either typesystem, and disallow some cases
>> which might have certain semantics within a pure static typesystem but
>> which are invalid within the dynamic typesystem. However, this would be
>> somewhat incompatible with how templates tend to be used in C++.
>>
>>
>>>> But what about generic containers?
>>>> How about we have some other way of building containers which isn't so
>>>> prone to be misused and hose everything?...
>>>>
>>>>
>>>> But what could such an alternative possibly look like?
>>>>
>>>> How about we have a few types, lets call them 'auto' and 'variant',
>>>> which unlike most other types, take on the type of the things that are
>>>> passed to them. Similarly, they can be allowed in argument lists and as
>>>> a return type, then the function will operate on that type (calling a
>>>> function with 'auto' arguments may specialize the function over the
>>>> argument types, allowing for any implicit type promotions).
>>>
>>> Do you mean that instead of having to write something like:
>>>
>>> template <typename T>
>>> T add(T x, T y)
>>> {
>>>     return x + y;
>>> }
>>>
>>> it would be nicer and neater to be able to write :
>>>
>>> auto add(auto x, auto y)
>>> {
>>>     return x + y;
>>> }
>>>
>>>
>>> That would let you use a nice general "auto" indicator for the type, and
>>> make specialist functions as needed for the concrete type (or inline the
>>> code as appropriate).  Then there would be no need for the somewhat ugly
>>> and verbose template syntax.
>>>
>>> It turns out that the C++ designers thought that too, and this is now
>>> valid syntax that means exactly the same as the template version.
>>> (Templates are a lot more flexible, and can have non-type template
>>> parameters, but for cases like this "auto" is a valid alternative
>>> syntax.)
>>>
>>
>> Yeah.
>>
>>
>> I can note that this was the direction I had been going in my own
>> languages, as it is related to the same general issue of getting
>> "non-horrible" performance from dynamically typed code.
>>
>>
>> In this case, every time one calls a function with auto args, it checks:
>>   Do we have an existing copy with these argument types.
>>     If so, use that one.
>>   Has the expansion limit been hit, ...
>>     If so, use a dynamically-typed fallback.
>>   Make a copy of the function with the given argument list.
>>     All the 'auto' arguments are replaced with concrete types;
>>     The types of other variables are type-inferred;
>>     The return type is also type-inferred.
>>
>> Internally, the function uses type-inference to figure out the types.
>>
>>
>> In cases where 'auto' is used with a type which can't be safely reduced
>> to 'variant' or similar, this would effectively force instantiation (as
>> a static type) even if the expansion limit had already been reached.
>>
>
> You are describing a very different kind of "auto" from C++ (and also a
> very different kind of "variant" from C++ std::variant).
>

Both of cases derive from BGBScript, not from C++, they just happen to
use similar terms, and do vaguely similar things...

And, the "C++ mode" that exists in BGBCC at present is not actually C++,
but more an ugly hack using BGBScript features on top of C, with a more
C++ flavored syntax.

Note that 'auto' by itself is not dynamically typed, but is instead
replaced by another type, such as 'int'.

The question then is whether it can, instead of converting to, say,
'int', be allowed to also convert to 'variant' (such as when due to
running into an expansion limiter).

This could be problematic in C or C++, given that many types in a C
style static typesystem can't be recreated accurately in a practical
dynamic type system (and 'auto' is assumed to always follow the same
rules as the static typesystem).

Even simple types like 'int' or 'unsigned int' are problematic, since if
one promotes them to a larger signed integer type and does arithmetic on
them, they may not necessarily get the same results.

This was more acceptable in BS2, since it can leave these semantics as
essentially undefined in this case.

In the past, a sort of similar mode had also been attempted to mimic C#,
which could almost work, but faces the (potentially very obvious)
difference that BS2 does not use a traditional garbage collector (though
there is the considered possibility of adding support for the use of a
reference-counting GC).

Note that some support for automatic storage duration objects is
supported, using essentially the same mechanism I used for implementing
"alloca" and VLAs in C (namely, putting all the allocations into a
linked list, which are then freed when the function returns).

The original idea was that it would be made explicit (via language
syntax) what the intended lifespan of an object was.

Eg:
FooObj obj = new FooObj(); //unbounded lifespan
FooObj obj = new! FooObj(); //automatic lifespan
And, considered (generally unimplemented):
FooObj obj = new(pool) FooObj(); //lifespan bounded by pool
delete pool; //delete everything associated with the pool

Similar also applied to lambdas.

SubjectRepliesAuthor
o Minor idea for indirect target predictor

By: Paul A. Clayton on Sat, 26 Jun 2021

188Paul A. Clayton
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor