2

I was just experimenting with C++. I was trying to write a small macro so that all the functions that I define are automatically stored in a map so that I can query, at run time, what functions exist and run them too. The code is as follows:

#include <map>
using namespace std;

typedef void (*funcPointer)();

map <char*, funcPointer> funcList;

#define Function(x) void x() { funcList[#x] = x; 
#define End }

I was used funcPointer and End only for easy readability and implementation. Now, I can define a function as

Function(helloWorld)
    cout << "Hello World";
End

Now, to read the function names as a list and run all the functions, I use the following code:

int main() {
    //helloWorld();
    for (map<char*, funcPointer>::iterator I = funcList.begin(); I != funcList.end(); I++) {
        printf(I->first);
        I->second();
    }
    getchar();
    return 0;
}

The problem is, if I keep the first line of main() (helloWorld();) commented, the compiler doesn't compile the function and skips it for optimization, as according to the compiler, it is never used. So, the function list turns up empty. If, instead, I call the function once, every thing works perfectly, except that it prints "Hello World" twice. Also, I wrote the macro specifically so I do not have to do that.

So, is there any way that I can force the compiler to compile a function even if it is not used?

Niall
  • 30,036
  • 10
  • 99
  • 142
  • 1
    Note that the C++ standard prohibits `void main()`, though I suppose there might be compilers that allow it as an extension even though the standard says otherwise. – Jonathan Leffler Oct 06 '14 at 03:43
  • 2
    No, macro make it harder to read. and you approach is totally wrong because you have to call the function to register it. it have nothing to do with optimization. – Bryan Chen Oct 06 '14 at 03:44
  • possible duplicate of [How can I force GCC to compile functions that are not used?](http://stackoverflow.com/questions/4182338/how-can-i-force-gcc-to-compile-functions-that-are-not-used) – Dwayne Towell Oct 06 '14 at 03:46

2 Answers2

5

The problem is that the code to register the function is inside the function, so won't happen unless you call the function. You might instead register it by initialising a global variable, which will happen automatically before main begins. This might look something like

struct funcRegistration {
    funcRegistration(char * name, funcPointer func) {funcList[name] = func;}
};

#define Function(x) \
    void x(); \
    funcRegistration x##_registration(#x, x); \
    void x() {
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 1
    now, welcome to the world of static initialization problems :) These statements are not guaranteed to be executed until the point at which a function is called in the same translation unit. For more discussion of this topic look up *Factory pattern*. – M.M Oct 06 '14 at 04:01
2

The compiler compiles the function, however your map won't be populated unless its called.

Because funcList[#x] = x; comes inside the function block { } after macro expansion.

P0W
  • 46,614
  • 9
  • 72
  • 119
  • 1
    @BryanChen it still has to check the function is syntactically valid (I guess that is a subset of compilation) – M.M Oct 06 '14 at 03:47
  • @MattMcNabb that's true. I guess the correct wording is include the function in the binary – Bryan Chen Oct 06 '14 at 03:48