jeudi 2 mars 2017

Static const data member defined in another file

I'm working on a static analyzer for C++11. There is an interaction between static const members of a class and linkage for which I am not sure whether it is defined. My static analyzer should warn for it only if this construct is not defined.

The example is this one:

in file f1.cpp:

struct Foo {
    static const int x = 2;
};

int main(void) {
    return *&Foo::x;
}

and in file f2.cpp:

struct Foo {
    static int x;
};

int Foo::x;

The two files compiled and linked with clang++ -std=c++11 -Weverything f1.cpp f2.cpp cause no warning and produce a binary that returns 0. The same files when compiled with g++ -std=c++11 -Wall -Wextra -pedantic f1.cpp f2.cpp cause no warning and return 2.

My intuition is that this program is ill-defined but no warning is required, as:

  • both names Foo::x have external linkage following N3376[basic.link]p5:

    In addition, a member function, static data member,[...] has the typedef name for linkage purposes (7.1.3), has external linkage if the name of the class has external linkage.

  • but they break the N3376[basic.link]p10 requirement:

    After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the types specified by all declarations referring to a given variable or function shall be identical [...] A violation of this rule on type identity does not require a diagnostic.

To be 100% sure about this, a definition for these "all adjustments of types" is needed, but seems nowhere to be found in the C++11 standard. Is there any, and is the reasoning above correct?

Aucun commentaire:

Enregistrer un commentaire