stałe globalne constexpr w pliku nagłówkowym i odr

Niestety, jestem nieco zdezorientowany constexpr, stałymi globalnymi zadeklarowanymi w plikach nagłówkowych i odr.

W skrócie: czy możemy stąd wywnioskować

Https://isocpp.org/files/papers/n4147.pdf

Że

constexpr MyClass const MyClassObj () { return MyClass {}; }
constexpr char const * Hello () { return "Hello"; }

Jest lepsze niż

constexpr MyClass const kMyClassObj = MyClass {};
constexpr char const * kHello = "Hello";

Do definiowania globali w pliku nagłówkowym jeśli chcę" po prostu użyć " tych globalnie zadeklarowanych/zdefiniowanych Bytów i nie chcę myśleć o Jak ich używam?

Author: Chris Beck, 2015-12-24

1 answers

Uwaga: począwszy od C++17, możesz zadeklarować swoje zmienne jako inline.


TL; DR: jeśli chcesz być po (bardzo) bezpiecznej stronie, skorzystaj z funkcji constexpr. Nie jest to jednak z natury konieczne i na pewno nie będzie, jeśli wykonujesz trywialne operacje na tych obiektach i jesteś wyłącznie zainteresowany ich wartością, lub po prostu nie używaj ich w niebezpiecznych scenariuszach wymienionych poniżej.

Podstawowym problemem jest to, że const zmienne w przestrzeni nazw takie jak twoje (ogólnie) mają wewnętrzne powiązania ([podstawowe.link]/(3.2)). Oznacza to, że każda jednostka tłumaczenia kompilująca odpowiedni nagłówek będzie obserwować inną jednostkę (tj. symbol).

Teraz wyobraź sobie, że mamy szablon lub funkcję inline w nagłówku, używając tych obiektów. ODR jest bardzo precyzyjny w tym scenariuszu- [basic.def.odr]/6:

Tutaj wpisz opis obrazka

"inicjowane wyrażeniem stałym" jest z pewnością spotkałam się, skoro rozmawiamy constexpr. Tak jest " obiekt ma taką samą wartość we wszystkich definicjach D" jeśli się nie zamilkniesz.

"obiekt nie jest odr-używany" jest prawdopodobnie jedynym wątpliwym warunkiem. Zasadniczo wymaga to, aby nie wymagać istnienia zmiennych runtime jako symbolu, co z kolei implikuje, że

  • Nie przywiązujesz go do referencji (=>Nie przesyłasz go!)

  • Ty nie (ani jawnie ani w sposób dorozumiany) przyjąć jego adres.

Jedynym wyjątkiem od drugiej reguły są tablice, które mogą być brane pod adres niejawnie wewnątrz operacji indeksu dolnego, o ile dwie powyższe reguły nie zostaną naruszone dla otrzymanej wartości glvalue.

Dokładniej, ODR-use jest regulowany przez [basic.def.odr]/3:

Zmienna x, której nazwa pojawia się jako potencjalnie oceniane wyrażenie ex, jest odr-używana przez ex, chyba że na konwersja lvalue-to-rvalue (4.1) na x daje wyrażenie stałe (5.20), które nie wywołuje żadnych nietrywialnych funkcji i jeśli x jest obiektem, ex jest elementem zbioru potencjalnych wyników wyrażenia e, gdzie albo konwersja lvalue-to-rvalue (4.1) jest zastosowana do e, albo e jest wyrażeniem odrzuconej wartości (Klauzula 5).

Zastosowanie l-t-R do dowolnej zmiennej constexpr zachowa się zgodnie z wymaganiami pierwszej części. Druga część wymaga, aby zmienna może być używana jako wartość , a nie rzeczywisty obiekt ; to znaczy, że jest ostatecznie odrzucana lub bezpośrednio oceniana, biorąc pod uwagę powyższe zasady.

Jeśli unikniesz odr-użycia zmiennej wewnątrz funkcji wbudowanych, szablonów lub tym podobnych, jesteś w porządku. Ale jeśli użyjesz wartości zwracanej przez odpowiednią funkcję constexpr, nie będziesz musiał się martwić, ponieważ wartości PR zachowują się już bardziej jak wartości/literały (Nie obiekty), a funkcje constexpr są wbudowane i na pewno nie będzie naruszać ODR (jeśli nie używasz zmiennych constexpr wewnątrz!).

 15
Author: Columbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-03 12:10:11