Question

Our system has a plugin-based architecture with each module effectively having a 'main' function. I need to have a small piece of code run before a module's main() is invoked. I've had success putting the code in the constructor of a dummy class, then declaring one static variable of that class, eg:

namespace {
class Dummy {
public:
    Dummy() { /* do work here */ }
};

   Dummy theDummy;
}

void main() {...}

This seems to work well, but is it a valid solution in terms of the compiler guaranteeing the code will run? Is there any chance it could detect that theDummy is not referenced anywhere else in the system and compile/link it away completely, or will it realise that the constructor needs to run? Thanks

Était-ce utile?

La solution

This seems to work well, but is it a valid solution in terms of the compiler guaranteeing the code will run? Is there any chance it could detect that theDummy is not referenced anywhere else in the system and compile/link it away completely, or will it realise that the constructor needs to run?

See n3797 S3.7.1/2:

If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused,

Yes, the initialisation has to run. It cannot be simply omitted.

See S3.6.2/4:

It is implementation-defined whether the dynamic initialization of a non-local variable with static storage duration is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first odr-use (3.2) of any function or variable defined in the same translation unit as the variable to be initialized.

Yes, the initialisation has to be completed before any code runs in the same translation unit.

The use of an entry point called main() in your plugin is of no particular importance.

You're good to go.


As per a comment, you do need to make sure that your Dummy constructor and your main function are in the same translation unit for this to work. If they were compiled separately and only linked together this guarantee would not apply.

Autres conseils

Don't call your function main() unless it is a program entry point. If it is, then you are guaranteed that static object constructors will be called before main().

Once main has started, it's guaranteed to run before any function or variable in the same translation unit is used.

So if, as here, it's in the same translation unit as main, then it's guaranteed to run before main. If it's in another transation unit, then it's implementation-defined whether it will be run before main. In the worst case, if the program doesn't use anything from the same translation unit, it might not run at all.

In general, a compiler is allowed to optimize something out only if it can be sure that the semantics are the same. So if you call any function that it can't see into, for example, then it must assume that the function has side effects, and won't optimize the code out.

Note that you may have initialization order issues between translation units, however, since the initialization order of static objects between TUs is in general not guaranteed. It is, however, guaranteed that the constructor will be called before the "main" for your module is entered (assuming same TU). See Section 3.6.2 of the C++11 standard for full details.

If a platform-specific mechanism will work for you, look into using a function attribute, which is supported by g++ and clang++.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top