Of course, the answer is "no", because the people who wrote it thought really hard about it, however I want to know why.
Considering that (template-less) classes are often declared in header files, which are then included in several files which are compiled separately, sub-consider these two files:
file1.c
#include <cstddef>
struct Foo {
public:
int pub;
private:
int priv;
};
size_t getsize1(Foo const &foo) {
return sizeof(foo);
}
file2.c
#include <cstddef>
struct Foo {
public:
int pub;
private:
int priv;
};
size_t getsize2(Foo const &foo) {
return sizeof(foo);
}
In general Foo will be declared in a header file and included in both, but the effect is as shown above. (That is, including a header is no magic, it just puts the headers content on that line.) We can compile both and link them to the following:
main.cc
#include <iostream>
struct Foo {
public:
int pub;
private:
int priv;
};
size_t getsize1(Foo const &);
size_t getsize2(Foo const &);
int main() {
Foo foo;
std::cout << getsize1(foo) << ", " << getsize2(foo) << ", " << sizeof(foo) << '\n';
}
One way to do so, is by using g++:
g++ -std=c++11 -c -Wall file1.cc
g++ -std=c++11 -c -Wall file2.cc
g++ -std=c++11 -c -Wall main.cc
g++ -std=c++11 -Wall *.o -o main
And (on my architecture and environment), this shows: 8, 8, 8. The sizeof's are the same for each compilation of file1.cc, file2.cc and main.cc
But does the c++11 standard guarantee this, is it really OK to expect to have layout compatibility with all 3 Foo's? Foo contains both private and public fields, hence it is not a standard-layout struct as is defined in Clause 9 par 7 of the c++11 standard (working draft):
A standard-layout class is a class that:
- has no non-static data members of type non-standard-layout class (or array of such types) or reference,
- has no virtual functions (10.3) and no virtual base classes (10.1),
- has the same access control (Clause 11) for all non-static data members,
- has no non-standard-layout base classes,
- either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
- has no base classes of the same type as the first non-static data member.
Since we are using structs, and to be thorough, the next par says:
A standard-layout struct is a standard-layout class defined with the class-key struct or the class-key class. A standard-layout union is a standard-layout class defined with the class-key union.
To the best of my knowledge, the standard only defines layout-compatibility between structs in standard layout (Clause 9.2, par 18).
Two standard-layout struct (Clause 9) types are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in declaration order) have layout compatible types (3.9).
So is it guaranteed all three Foo's are layout-compatible, and more importantly why?
Why would a (non-deterministic) compiler, which creates different layouts for Foo during compilation, not be a c++11 compiler?
Foo
refer to the same entity, which must have the same set of properties in all translation units. To that end, all the definitions must be token-for-token identical, and the tokens must have the same meaning; otherwise, the program is ill-formed, no diagnostic required. See 3.2/5 for details. – Beatnik