Czy mój program będzie zawierał 100 kopii każdego ciągu liter i liter, jeśli uwzględnię go w 100 jednostkach? Czy skopiowane zostaną tylko wskaźniki i wartości?
Standard nie obiecuje konsolidacji literałów ciągów, więc to zależy od implementacji.Prosty test wykorzystujący GCC 5.1.1 na GNU/Linux pokazał, że literały łańcuchowe są nie skonsolidowane w niezoptymalizowanej kompilacji, ale są konsolidowane, gdy jest używany. Ale to tylko połączenie rzeczywistych tablic char
. W zakresie, w którym kompilator nie optymalizuje pamięci dla wskaźnika lub stałych numerycznych (jeśli są one lokalne dla jednostki tłumaczeniowej, a nie dla ODR i typu POD, są oczywistymi kandydatami do eliminacji w ramach as-if), jednak kompilator może nie być w stanie ich łatwo skonsolidować. Standard wymaga, aby były różnymi obiektami i dlatego muszą mieć różne adresy. Reguła as-if może nadal zezwalać na ich usunięcie, nawet jeśli masz wziąć ich adresy, ale generalnie wymagałoby to optymalizacji globalnego programu, np. Optymalizacji czasu łącza, w tym bibliotek, których implementacja może nie obsługiwać, obsługiwać tylko w ograniczonym zakresie i/lub tylko w zależności od ustawień kompilatora i linkera. Innymi słowy, może się to zdarzyć w odpowiednich okolicznościach, ale jest o wiele bardziej prawdopodobne, że tak się nie stanie.
Moje własne badania wskazują, że GCC 5.1.1 nie konsoliduje static const unsigned int
przedmioty wystawione przez const
ref, nawet z -Os -flto
(optymalizacja pod kątem wielkości i umożliwiają optymalizację link-time). Szczerze mówiąc, byłbym zaskoczony, gdyby jakakolwiek współczesna implementacja wykonała tę trudną i niejasną optymalizację.
(też jestem zgadywania „statyczne” jest zbędne w tym użytkowania, ale chciałbym umieścić go tam i tak)
To nie jest zbędny, jeśli masz wiele jednostek tłumaczeniowych, ponieważ w przeciwnym razie przebiegają wbrew zasadzie jednej definicji (ODR). Na marginesie jednak, static
w zakresie przestrzeni nazw było przez długi czas uważane za składnie przestarzałe (zamiast tego należy rozważyć użycie anonimowych przestrzeni nazw wprowadzonych w C++ 98).
(. W odpowiedzi na okrzyki i HTH - Alf)
Jeśli chcesz mieć pewność, tylko jedna kopia każdej stałej, lub nawet bez kopii, a następnie można użyć szablonu klasy, podobnie jak to:
Nie ma szczęścia. W standardzie nie ma gwarancji, ile miejsca zajmuje szablon. Cały szablon gwarantuje, że tylko jedna z potencjalnie wielu kopii jest używana - lub wydaje się być używana - zgodnie z zasadą "jak to". W rzeczywistości jest to gorsze, ponieważ przynajmniej GCC 5.1.1 w rzeczywistości nie nie usunąć nadmiarowy static const unsigned int
nawet z -Os -flto
w moim systemie. Oznacza to, że w przypadku dwóch jednostek tłumaczeniowych wartość inicjalizatora dla unsigned int
można znaleźć w dwóch oddzielnych lokalizacjach, mimo że używana jest tylko jedna z nich (wszystkie wskaźniki i odniesienia odnoszą się tylko do tej lokalizacji).
Co więcej, szkic C++ 17 ma zmienne 'inline'. – Simple
To robi ** nie **, unikając konieczności definiowania tych zmiennych w innym pliku. Są to deklaracje iw wielu przypadkach nie trzeba podawać definicji, ale w niektórych przypadkach nie. Na przykład, jeśli przekażesz jedną z tych stałych do funkcji, która przyjmuje ją przez odniesienie, będziesz potrzebować definicji. –