Ještě typedefs šablon zachovat statické inicializační objednávku?

hlasů
3

V rámci stejné kompilační jednotce C ++ standardní říká, že statická inicializace objednávka je dobře definován - je to pořadí prohlášení statických objektů. Ale s použitím Sun Studio 12 kompilátor jsem se setkávat unintuitive chování. Mám definovat templátovanou třídu helper<T>, která obsahuje statické člen _datatypu Ta funkci statický člen, který používá _datas názvem foo. V mém souboru cpp mám to výše main ():

struct A { /* some definition */ };

typedef helper<int> s0;
typedef helper<A> s1;

Všimněte si, že definice typu pro helper<int>přichází dříve, než je definice typu pro helper<A>. Takže v souladu s normou Očekával bych, že helper<int>::_databude postavena před helper<A>::_data(nezapomeňte _dataje statický člen). Na GCC je to váš případ, na slunci není.

To je problematické, protože je konstruktér použije helper<int>::_data. Mám jen jednu kompilaci jednotky bez předchozího potenciální instance helper<A>, tak jsem si myslel pořadí by měl být dobře definovány. Je to Sun kompilátor chyba, nebo dělá typedef nepředstavuje Definice / instance technicky? Co mám na mysli je, je chování Sun kompilátoru povolené normou?

Mám následující main ():

int main()
{
    //Swapping the order of these has no effect on Sun
    s0::foo();
    s1::foo();
}

Neexistují žádné jiné využití s0 a s1.

Položena 10/07/2009 v 16:54
zdroj uživatelem
V jiných jazycích...                            


2 odpovědí

hlasů
6

V rámci stejné kompilační jednotce C ++ standardní říká, že statická inicializace objednávka je dobře definován - je to pořadí prohlášení statických objektů.

Ve vašem zobrazeném kódu nemáte prohlášení o statický datový člen. Máte deklaraci typedef-name. Ty nemají nic společného s tím, a nemají vliv na libovolném pořadí. Asi si myslíte, že po této cestě :

Pokud se i učinit toto prohlášení typedef, bude instance helper<int>, a tak konkretizovat svou statickou prohlášení člena dat jako první.

Problém je v tom, že řada nezpůsobí konkretizaci helper<int>. Aby se tak stalo, museli byste explicitní instance nebo úpravy, aby bylo instanci implicitně (vytvořit objekt helper<int>například, nebo používat to jako vnořené jméno specifikátorem jako v helper<int>::...a explicitně odkazování na statický člen - jinak, tvorba z nich je vynechány).

Ale je tu mnohem hlubší problém. Objednávka je to prohlášení statických datových členů. Pořadí je jejich definice . Zvažte následující

struct C { C() { printf("hey\n"); } };
struct A { 
  static C a;
  static C b;
};

C A::b;
C A::a;

V tomto kódu, b je vytvořena před , přestože A je deklarován před b .

Následující kód vytiskne 2 1:

struct C { C(int n) { printf("%d\n", n); } };

template<int N>
struct A {
  static C c;
};

template<int N>
C A<N>::c(N);

// explicit instantiation of declaration and definition
template struct A<2>;
template struct A<1>;

int main() {

}

Ale následující kód vytiskne nic, není-li se vyjádřit v řadě v main.

struct C { C(int n) { printf("%d\n", n); } };

template<int N>
struct A {
  static C c;
};

template<int N>
C A<N>::c(N);

// implicit instantiation of declarations
A<2> a2;
A<1> a1;

int main() {
  // A<1>::c; A<2>::c;
}

Nejsem si vlastně jistý, co správný výstup tohoto druhého úryvku je. Čtení normu, nemohu určit pořadí. To říká, že při 14.6.4.1„Point of instance“:

Pro funkce šablony oborového členské funkce šablony specializace nebo specializace na členské funkce nebo statické datový člen šablony třídy, v případě, že specializace je implicitně instance, protože je odkazováno z jiné šablony specializace [...]. V opačném případě je bod instance pro takovou specializaci bezprostředně navazuje na deklaraci rozsah názvů nebo definici, která odkazuje na specializaci.

Smyslem konkretizaci svých definic oba se objeví bezprostředně po definici main. Která definice je instance předtím, než se zdá, že druhá definice má být vlevo nespecifikovaná. Pokud někdo zná odpověď a khow další kompilátory chovat (GCC otisky 1 2, ale s pořadím výrazů v mainprohozené, tisky 2 1), dejte mi prosím vědět v komentáři.

Podrobnosti najdete v tuto odpověď o životě statickém objektu .

Odpovězeno 10/07/2009 v 17:05
zdroj uživatelem

hlasů
0

Nejste vlastně prohlašují všechny objekty v tomto kódu.

Budete potřebovat další kód:

s0 one;
s1 two;

V takovém případě jsou dva objekty jsou nyní skutečně deklarované, a měl by fungovat správně.

Jsou explicitně deklarování S0?

Zkuste v návaznosti na typedefs s s0 figuríny; a zjistit, zda je problém vyřešen.

Odpovězeno 10/07/2009 v 17:01
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more