1 2 3 4 5 | RecordDebugEvent(int RecordIndex, debug_event_type EventType, u8 TranslationUnit = TRANSLATION_UNIT_INDEX) { ... Event->TranslationUnit = TranslationUnit; } |
The constructor and destructor should always be in the same translation unit themselves, right? So if you make sure that the functions they call also are (by for example my second method) you should be fine.
aameen951
The functions that are marked as inline are different from the regular ones
the body of the inline function need to be defined in the header so anyone will call it can see it and the compiler can inline it.
In the case where the compiler decide not to inline the function, my guess is it will treat the function as static.
In both cases the linker won't even see it.
When an inline function is not static, then the compiler must assume that there may be calls from other source files; since a global symbol can be defined only once in any program, the function must not be defined in the other source files, so the calls therein cannot be integrated. Therefore, a non-static inline function is always compiled on its own in the usual fashion.I think msvc does something similar. It generates one global symbol and therefore messes up our expectation of one version of RecordDebugEvent per translation unit.
If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required.
An inline function with external linkage shall have the same address in all
translation units.
So I guess it's kinda right, but it feels so wrong ...
There can be more than one definition of a class type (clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (clause 14), non-static function template (14.5.5), static data member of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.4) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.
Given such an entity named D defined in more than one
translation unit, then
— each definition of D shall consist of the same sequence of tokens;
This is violated in the Handmade Hero Source
...
If the definitions of D do not satisfy these requirements, then the behavior is undefined.
Mox
But if it really made it static the problem should not exist. Because then the translation units would never be mixed. Here the problem occurs because not inlining the function only produced one version of the code. If the linker really didn't see the function you would get one version for every translation unit, each with the correct constant for the TranslationUnit variable. So in my opinion it is not the inlining that is the problem, but the placement of the function if it is not inlined.
If the definitions of D do not satisfy these requirements, then the behavior is undefined.I don't know what they mean by "undefined"?
aameen951
I don't know what they mean by "undefined"?
Does it mean that the compiler doesn't need to check for this? I don't know.
Sounds like the compiler can do whatever it wants
behavior for which this International Standard imposes no requirements
[ Note: Undefined behavior may be expected when this International Standard omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data. Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed.
— end note ]