2011-03-07 15 views
9

Gdy masz statyczną zmienną globalną w pliku nagłówkowym C++, każda jednostka tłumaczeniowa, która zawiera plik nagłówkowy, kończy się własną kopią zmiennej.Statyczna zmienna globalna używana przez funkcję inline member

Jeśli jednak zadeklarować klasę w tym samym pliku nagłówka i utworzyć funkcję członka tej klasy, realizowanego inline w deklaracji klasy, który używa zmiennej statycznej globalnej, na przykład:

#include <iostream> 

static int n = 10; 

class Foo { 
public: 
    void print() { std::cout << n << std::endl; } 
}; 

potem widzę nieco dziwne zachowanie pod gcc 4.4:

  1. Gdybym kompilacji bez optymalizacji, wszystkie zastosowania funkcji członka wykorzystać kopię zmiennej z jednej z jednostek tłumaczeniowych (pierwszy wspomniano na g ++ polecenia linia).

  2. Jeśli kompiluję się z -O2, każde użycie funkcji składowej wykorzystuje kopię zmiennej z jednostki tłumaczeniowej, w której jest wykonywany przypadek.

Oczywiście jest to naprawdę zły projekt, więc to pytanie jest tylko z ciekawości. Jednak moje pytanie brzmi: co standard C++ mówi o tej sprawie? Czy g ++ zachowuje się poprawnie, podając inne zachowanie przy włączonej optymalizacji i bez niej?

+1

Prawdopodobny duplikat: [statyczne słowo kluczowe w pliku h i wewnętrzne powiązanie] (http://stackoverflow.com/questions/4276794/static-keyword-in-h-file-and-internal-linkage). –

Odpowiedz

12

Norma mówi (3,2/5):

Nie może być więcej niż jedna definicja typu klasy (pkt 9), ... pod warunkiem, że spełniają definicje następujące wymagania .. . definicja w każdym D, co odpowiada nazwisk sprawdzana zgodnie 3.4, są odnosi się do jednostki określonym w definicji D lub odnoszą się do tego samego podmiotu

Tutaj następuje utrata kodu. Zastosowania n w różnych definicjach Foo nie odnoszą się do tego samego obiektu. Koniec gry, niezdefiniowane zachowanie, więc tak, gcc ma prawo robić różne rzeczy na różnych poziomach optymalizacji.

3,2/5 kontynuuje:

z tym, że nazwa może odnosić się do obiektu const z wewnętrznym lub bez wiązanie, jeśli obiekt ma taką samą integralną lub wyliczania rodzaju we wszystkich definicji D a obiekt inicjowany stałej ekspresji (5,19), a wartością (nie adres ) przedmiotu jest stosowany i obiekt ma taką samą wartość w każdym definicji D

W swoim przykładowym kodzie można ustawić n w static const int i wszystko będzie urocze. To nie zbieg okoliczności, że w tym punkcie opisano warunki, w których nie ma znaczenia, czy różne JT "odnoszą się" do tego samego obiektu, czy do różnych obiektów - wszystko, czego używają, to stała wartość czasu kompilacji i wszystkie używają tej samej.

+1

+1: Czasami ODR zostaje naruszona w bardzo subtelny sposób. –

+0

Doskonała odpowiedź. Dziękuję Ci. – jchl