Является ли «фиаско статического порядка инициализации» проблемой для переменных constexpr? - PullRequest
0 голосов
/ 17 мая 2018

Если я инициализирую переменную constexpr foo значением, отличным от значения по умолчанию, в одной единице перевода, а затем инициализирую другую переменную constexpr bar с foo в другой единице перевода, возможно ли это для bar должен быть инициализирован до foo, что приведет к bar, который был инициализирован инициализированным нулем или по умолчанию foo. то есть в отличие от случая, не связанного с constexpr (где действует статический порядок инициализации fiasco), будет ли компилятор и компоновщик анализировать упорядочение зависимостей, чтобы гарантировать правильный результат?

Кроме того, как влияют шаблоны переменных constexpr? Их порядок инициализации не определен В пределах единичных единиц перевода.

C ++ 17 стандартных ответов предпочтительнее.

UPDATE: Вот минимальный пример. Оно работает; Это проблема. На данный момент я на 99% уверен, что это безопасно от Статический порядок инициализации Fiasco (TSIOF) . Однако из-за крайней, коварной природы этой проблемы мне нужно получить подтверждение, что это нормально. Я полагаю, этот код не страдает от TSIOF, так как включение y.h в x.h приказов a и b в единице перевода x.cc. Однако в AFAIU есть 2 единицы перевода: одна содержит a, другая содержит b. Кроме того, AFAI-sort-of-U ошибка множественного определения a не возникает, поскольку ключевое слово static передает внутреннюю связь , но a все еще имеет глобальную scope .

скомпилировано с:

clang++ -std=c++17 x.cc y.cc  #or g++

возможный вывод:

in foo

возможный вывод:

assertion failed (core dumped)

файл x.cc:

#include "x.h"
int main(){ assert(b == 42); foo(); }

файл x.h:

#pragma once
#include "y.h"
static constexpr int b = a+1;

file y.cc:

#include "y.h"
#include <iostream>
void foo(){
    std::cout << " in foo \n";
}

file y.h:

#pragma once
static constexpr int a=41;
void foo();

Эта программа гарантирует вывод in foo?

Поскольку на этот вопрос нельзя ответить в качестве примера, ему действительно нужен языковой адвокат для предоставления соответствующих стандартных цитат

Этот вопрос о STIOF в разных единицах перевода. Связанный без ответа вопрос о STIOF в единицах перевода для шаблонных переменных: здесь

1 Ответ

0 голосов
/ 19 мая 2018

В вашем примере возможной проблемы нет, поскольку a в y.cc - это переменная, отличная от a в x.cc. Таким образом, не происходит перекрестного связывания единиц измерения.

Фактически, не может быть перекрестной единицей связи между переменными constexpr. Весь смысл constexpr в том, что значение рассчитывается во время компиляции.

Другими словами, constexpr должен разрешить значение, пока мы все еще компилируем единицу перевода.

Из-за этого статический порядок инициализации Fiasco неявно не применяется к constexpr переменным, и в стандарте нет необходимости упоминать, что делать в этом сценарии.

Редактировать: в соответствии с запросом соответствующая часть стандарта: 10.1.5 (9) [dcl.constexpr]

В любом объявлении переменной constexpr полное выражение инициализация должна быть константным выражением (8.20).

Что приводит к 8.20 (1) [expr.const] со следующим примечанием:

[Примечание: константные выражения могут быть оценены во время перевода. - конец примечания]

Что является обоснованием для следующей страницы с половиной пунктов, но само по себе достаточно, чтобы исключить перекрестные ссылки на единицы измерения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...