Разбира се, отговорът е „не“, защото хората, които са го написали, много са го обмислили, но искам да знам защо.
Като се има предвид, че класовете (без шаблони) често се декларират в заглавни файлове, които след това се включват в няколко файла, които се компилират отделно, разгледайте тези два файла под:
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);
}
По принцип Foo ще бъде деклариран в заглавен файл и включен и в двата, но ефектът е както е показано по-горе. (Тоест включването на заглавка не е магия, то просто поставя съдържанието на заглавките на този ред.) Можем да компилираме и двете и да ги свържем със следното:
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';
}
Един от начините да направите това е да използвате 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
И (на моята архитектура и среда) това показва: 8, 8, 8. Размерите са еднакви за всяка компилация на file1.cc, file2.cc и main.cc
Но дали стандартът c++11 гарантира това, наистина добре ли е да очакваме да имаме съвместимост на оформлението с всичките 3 Foo? Foo съдържа както частни, така и публични полета, следователно не е структура със стандартно оформление, както е дефинирано в клауза 9, параграф 7 от стандарта c++11 (работен проект):
Клас със стандартно оформление е клас, който:
- няма нестатични членове на данни от тип клас с нестандартно оформление (или масив от такива типове) или референция,
- няма виртуални функции (10.3) и виртуални базови класове (10.1),
- има един и същ контрол на достъпа (Клауза 11) за всички членове на нестатични данни,
- няма базови класове с нестандартно оформление,
- или няма нестатични членове на данни в най-производния клас и най-много един основен клас с нестатични членове на данни, или няма базови класове с нестатични членове на данни, и
- няма базови класове от същия тип като първия нестатичен член на данните.
Тъй като използваме структури и за да бъдем изчерпателни, следващият параграф казва:
Структурата със стандартно оформление е клас със стандартно оформление, дефиниран със структурата на класовия ключ или класовия ключов клас. Обединение със стандартно оформление е клас със стандартно оформление, дефиниран с обединението на класовия ключ.
Доколкото ми е известно, стандартът дефинира само съвместимост на оформление между структури в стандартно оформление (клауза 9.2, параграф 18).
Два типа структура със стандартно оформление (клауза 9) са съвместими с оформлението, ако имат еднакъв брой нестатични членове с данни и съответните нестатични членове с данни (в ред на деклариране) имат типове, съвместими с оформлението (3.9).
Така че гарантирано ли е, че и трите Foo са съвместими с оформлението и по-важното защо?
Защо (недетерминиран) компилатор, който създава различни оформления за Foo по време на компилация, не би бил c++11 компилатор?
Foo
се отнасят до един и същи обект, който трябва да има един и същ набор от свойства във всички единици за превод. За тази цел всички дефиниции трябва да бъдат идентични токен за токен и токените трябва да имат едно и също значение; в противен случай програмата е неправилно оформена, не се изисква диагностика. Вижте 3.2/5 за подробности. - person Igor Tandetnik   schedule 23.10.2014