since there is a small but measurable cost to both RTTI and C++ Exceptions just by their very existence
I would not say that exceptions have a small cost. GCC is still sometimes utterly incapable of producing code that works if you decide to use them. I would call that a serious cost, but it does not happen for everyone, just the unlucky ones, so statistically it might be small.
My proposals:
--- 1 ---
For vtables, I would suggest implementing non-export vtables. The advantage is that you would know all the implementation functions and thus be able to use a smaller integer to point to a vtable, allowing some of the functions to be compiled into devirtualized functions with top-level switch statements for implementation resolution, if they're small enough for that.
The downside is, of course, that you can't override such classes across dynamic module boundaries. Or, if you do, the overrides would perform as usual, not having the benefits of this optimization.
--- 2 ---
Inline calls. This can be worked around but since it's such a small issue, why not do it the right way - by adding a special attribute to the call that would inline just the function call, if possible.
--- 3 ---
Manual struct layouts. Something like...
struct large_int
{
uint32_t high @ 0;
uint32_t low @ 4;
uint64_t wide @ 0; // overlaps both previous members
};
This would simplify data structures and their reinterpretation, allow to define interface structs (such as event type/data structs) easier.
--- 4 ---
An "I know what I'm doing" cast: "jiggabyte* ptr = %% &car_object.private_thing;" I realize that auto solves many of those problems (the horrible reinterpret_cast type retyping) but it doesn't solve all. For example, it is still impossible to cast from member function pointers and access private member variables. This is necessary sometimes as it happens to be a better solution than messing with the source. And, of course, an optional compiler warning could be created that prints all occurrences of this cast.
--- 5 ---
Setters and getters: defining a function with a __set__ or __get__ prefix would create a function that is triggered on a property. __get__ could return either a reference or value, to help avoid the issues that are present in C# and similar languages. Additionally, a prefix could be added for accessing such properties, to make the user acknowledge the presence of a getter (and the performance hit that may come with it).
--- 6 ---
Make externally defined operators contextually equal to internally defined ones in that they're able to return "temporary" arguments passed by reference. This is useful for logging system extensions, such that there's an externally defined operator:
Logger& operator << ( Logger& me, const Thing& t ){ magic; return me; }
It works if the operator is defined inside the class, why shouldn't it work outside? Perhaps this has been fixed and I just don't know the way to do this right but I haven't managed to find anything on this except people saying "C++ can't do this". Because it should be able to. But perhaps the next proposal would solve this.
--- 7 ---
"this" arguments. Make their member variables equivalent to local ones, as if they were coming from the called class of a method.
Logger& operator << ( this Logger& me, const Thing& t ){ me.magic(); magic(); /* < equivalent to prev. call */ return me; }
--- 8 ---
Standard data dumping functions, automatically generated for structs and other types that don't have them. I'd like to be able to write "dump( x )" and it would print everything about "x", whatever it is, without a debugger. Additionally, I'd like to be able to specify my own class instance of a dumper, to be able to dump wherever I want. And it's important here not to lean on RTTI or anything that would add complexity and make dumping error-prone or unavailable for some.
Can't think of anything else ATM. Will add it when I can.