4 ms·
I've become a heavy user of a number of clang extensions, __attribute__((cleanup)) __attribute__((overloadable)) … are now indispensable to me. Cleanup I
by jws 11y ago
I've become a heavy user of a number of clang extensions,
__attribute__((cleanup))
__attribute__((overloadable))
… are now indispensable to me.
Cleanup I use for both object lifetime management (when it fits that model), and lock management. Typically a "get access" type of function will take the lock and return the pointer to the object. Then when that pointer goes out of scope the lock can be freed.
overloadable is perfect for keeping names under control. Consider if you have a bunch of structs for encoding various bit arrays. Maybe 32, 64, and 1024 bit long. Each has functions for working on it, so you either prefix all the functions with bit32_, bit1024_ or you pick a letter suffix, e.g. bitset(), bitsetl(), bitseth() (huge?), and try to make the programmer remember them all. With overloadable functions I get to use the same simple name for the operation and which implementation you use underneath is irrelevant.
I think I'd like to go one step further and sugar up the syntax so…
variable.func(a,b) <----> func( variable,a,b)
… but Mr. Stroustrup might call me names. But darn it, sometimes you want to think of your objects in different ways. I'd be using lisp if I wanted everything the same. (Actually, I suppose Kernel, and laughing at the lisp users who think they have uniformity.) It doesn't have to be ".", go ahead an create an "=>" notation if that helps with the ambiguity of structure reference. (No dynamic dispatch here. Just leverage overloadable.)
And here is the big one: Thread Safety Analysis. This has the potential to eliminate huge swathes of runtime problems in multithreaded code and even calling convention problems in single threaded code.
In a nutshell, you can annotate your program to make statements about objects. You can say an operation ACQUIRE's an object (takes a lock), and that another operation RELEASEs an object. Then you can declare that other options REQUIRE that the object be in the ACQUIREd state. There is more, such as declaring that a the execution is currently in a state and then restricting its ability to perform operations based on that.
The current implementation is probably bit rotting in gcc, and the clang version seems to be missing some important bits to making it useful. The C++ end of it apparently works for Google with their Android coding conventions, but the C end of it doesn't quite do it for me. I think with perhaps letting a function declare that its return value is ACQUIRE()d I might be able to put it to use. (And fixing the bit where it doesn't play well with __attribute__((cleanup)) ).
But the working group has a '2' in the name. We have 4 years.
And one more huge one: PLEASE add a paragraph to the spec that says:
"undefined" is NOT license for some language lawyer compiler writer to kill your dog, burn your garden, erase your disk and return 42 from the main program.
Undefined should mean "we understand different architectures and compilers might prefer to do this differently, implement something SANE and warn the user that they are on squishy ground".
- jws 11y agoIf they decided to hand out flying ponies… • blocks are pretty spiffy. • nested functions, by which I mean I don't need access to the parent's variables, I just want to tuck this little function inside the namespace of my existing function because darn it, it's two lines long and I can give it a tiny name, and I don't have to stick it above my giant function comment header where I can't see it while I'm in the code that is using it. I just want to abstract these two lines that I need to do three times in this function. gcc has these, clang thinks it's hard in their world.
- david-given 11y agogcc nested functions do have access to their parent's variables. Obviously only until the parent exits --- they're not closures. I would love for this to be in the standard, particularly if they come up with a nested function literal syntax. Having them would make things like mutation callbacks and foreach() so much cleaner.
- tveita 11y agoNested functions are convenient, but when you take the address of a nested function that refers to surrounding variables, GCC puts a small trampoline function on the stack. To do this it has to disable the no-execute flag on the stack, which makes it significantly easier to exploit stack overflow vulnerabilities in your program. Since the implementation is somewhat complex and system-specific, depends on memory that is both writeable and executable, and requires disabling security features on modern OSes, I doubt GCC style nested functions will make it into the standard.
- kps 11y ago> I think I'd like to go one step further and sugar up the syntax so… > variable.func(a,b) <----> func( variable,a,b) > … but Mr. Stroustrup might call me names. http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0251r0.pdf http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0251r0.... … but that's C++.