Comment by Y_Y
1 day ago
I guess they mean to overwrite the pointers:
void (*foo)(void)
int main(){
*foo();
}
void foo1(){...}
foo = &foo1; // will be overwritten later
void foo2(){...}
foo = &foo2;
I'm on my phone so I haven't compiled it, but that's the rough idea I got, define lots of versions and then set the version to the latest one.
(You can skip the address-of for functions by punning, but reading the types is hard enough already.)
That's not valid C; you can't put statements outside of functions, not even assignment statements or other expression statements. No C compiler I've ever used will accept it. Where would the compiled version of those statements go, in an init function? Linkers added support for those for C++ static initializers, where execution order isn't defined; C doesn't have anything similar. Are you expecting the compiler to execute the assignment statements at compile time, with a C interpreter?
(What's the language lawyer equivalent of an ambulance chaser?)
Fair point, I hadn't thought it all the way through. It's also all too easy to assume you can use C++ features or GNU extensions if you're not in the habit of enforcing the standard. For your trouble here are two partial solutions:
---
1. CPP abuse
If I was doing this myself I'd probably just use the preprocessor to make the last function my entry point like
and then you can start with
and append
and execution will start from the last defined function (that matches the regex).
---
2. Pre-defining non-static functions
If that's cheating then you can redefine "external" functions before the linker has a chance to provide them. For example:
is a valid program, and you can append
and foo will indeed be called. It does require some forward planning if you want to append multiple times, but it shouldn't be so difficult to generate a library full of dummy functions to use.
This isn't a language-lawyer kind of thing, and, as I said, I don't think C++ features or GNU extensions will help. The pre-defining extern functions approach will get you a finite number of tries, but I suppose it could be a fairly large finite number.
If for some reason I had to solve this problem in real life I would do it with a postprocesing step like your #1 suggestion. But once you're putting code into your Makefile anything goes.
4 replies →