2016-12-14 3 views
10

Следующий код не компилировать live on Ideone:Инициализация constexpr с сопзЬ: Different лечение междунар и двойной

#include <iostream> 
using namespace std; 

int main() { 
    const double kPi = 3.14; 
    constexpr double kPi2 = 2.0*kPi; 
    cout << kPi2; 
} 

Сообщение об ошибке:

prog.cpp: In function 'int main()': 
prog.cpp:6:30: error: the value of 'kPi' is not usable in a constant expression 
    constexpr double kPi2 = 2.0*kPi; 
          ^
prog.cpp:5:15: note: 'kPi' was not declared 'constexpr' 
    const double kPi = 3.14; 

Подставив const декларацию для kPi с constexpr, it compiles successfully.

С другой стороны, когда int используется вместо double, кажется, constplays well с constexpr:

#include <iostream> 
using namespace std; 

int main() { 
    const int k1 = 10; 
    constexpr int k2 = 2*k1; 
    cout << k2 << '\n'; 
    return 0; 
} 

Почему int и double получить различные процедуры для инициализации constexpr с const?
Является ли это ошибкой в ​​компиляторе Ideone? Это требуется стандарту C++? Почему это?
Был ли вышеуказанный код UB?

P.S. Я пробовал с компилятором Visual Studio 2015 C++, и он компилирует первый фрагмент кода (инициализация constexpr с const) просто отлично.

+2

[выпуск 1826: Const с плавающей точкой в ​​константных выражениях] (http://stackoverflow.com/a/30742473/1708801) охватывает некоторую историю о том, почему с плавающей точкой обрабатывается по-разному. Также [интересное устаревшее gcc exntension] (http://stackoverflow.com/q/32813953/1708801). –

+0

@ShafikYaghmour Спасибо. Я поддержал этот пост. –

+0

Похоже, что комментарий @ ShafikYaghmour должен быть доведен до ответа, а затем принят. – TriskalJM

ответ

-3

Правило: «constexpr следует оценивать по адресу время компиляции».

Давайте рассмотрим ниже код (общий пример);

const double k1 = size_of_array(); 

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

Но компилятор увидеть этот код:

const int k1 = 10; 
    constexpr int k2 = 2*k1; 

Одно исключения происходит. Значение constexpr integer может использоваться везде, где требуется целочисленное целое число, например, в аргументах шаблона и объявлениях массива[1].

Вы можете получить дополнительную информацию по ссылкам ниже:

  1. Constexpr - Generalized Constant Expressions in C++11
  2. const vs constexpr on variables | stackoverflow
  3. Difference between constexpr and const | stackoverflow
+0

Это не отвечает на вопрос, который был о 'const double k1 = 3.14;', а не о 'const double k1 = size_of_array();' –

+0

Конечно ** double k1 = size_of_array(); ** не включать в вопрос но я привел пример ** время компиляции ** и ** инициализацию времени выполнения ** о значении const. И этот пример о каждой переменной const не constexpr (постоянное выражение). И ответ на этот вопрос после этой информации: целочисленное значение constexpr может использоваться везде, где требуется целочисленное целое число, например, в аргументах шаблона и объявлениях массива. [MSDN] (https://msdn.microsoft.com/en-us /library/dn956974.aspx) – straceX

+0

Этот вопрос касается инициализации значения времени компиляции, нет никакого отношения к примеру инициализации во время выполнения. В вашем ответе кажется, что проблема с кодом OP - это инициализация времени выполнения. –

0

Шафик Ягмур уже предоставил link explaining the background.

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

#if __cplusplus <= 199711L // lower than C++11 
    #define MY_CONST const 
#else // C++11 and above 
    #define MY_CONST constexpr 
#endif 
Смежные вопросы