2014-11-03 3 views
7

Я изучаю Си ++ язык программирования C и в главе моей книги вводит меня понятие постоянной:Что такое значение, известное во время компиляции?

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

Что такое значение, известное во время компиляции? Почему мы нуждаемся в них?

+3

например: 'int x = 3.0f;', значение 'x' известно во время компиляции. – Borgleader

+4

Определение вводит в заблуждение - constexpr (в C++ 11) является значением или функцией, которая может быть оценена во время компиляции. –

+0

Связано с [«Константные выражения» до C++ 11] (http://stackoverflow.com/q/26024942/170880) ... в моем ответе есть много оснований для работы, которые могут быть полезны. То, что определяет постоянное выражение, трудно определить простым способом. –

ответ

1

Это означает, что программа не должна запускаться для вычисления константы. Например:

int num = 4; 

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

4

Что такое значение, известное во время компиляции?

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

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

Примерами являются

constexpr int i = 54; 
constexpr float f = 684; // Compile-time conversion from int to float 

constexpr int func(int i) 
{ 
    return i*47 % 23; 
} 

constexpr auto value = func(i * f); // Okay; constexpr function called 
            // with arguments that, when substituted inside, 
            // yield constant expressions 

Иногда значение фактически известно во время компиляции, но это выражение не является константой один в соответствии со стандартом. Это включает в себя

int i = 43; 
constexpr int j = reinterpret_cast<int>(i); // Shouldn't compile. (Does with GCC) 

Есть случаи были компилятор может сделать постоянное складывание - некоторые значения могут быть вычислены во время компиляции, но не должен быть.

int i = 0; 

for (int j = 1; j != 10; ++j) 
    i += j; 

return i; 

компилятор может полностью устранить петлю и инициализировать i с 55 (или просто вернуть 55 и устранить i тоже), пока поведение остается неизменным. Это называется the as-if rule.

+0

В этом случае сделать отчет о дефекте компилятору или стандартным [isocpp] (https://isocpp.org/). – Surt

+0

@Surt Я думаю, разработчики GCC хорошо знают об этом. – Columbo

+0

Я думал, что должен компилироваться, так как он в конечном счете оценивает i и если 'constexpr int j = i;' ОК, так что должно быть сделано выражение. – Surt

5

A constant expression означает выражение, которое может быть оценено во время компиляции (то есть до запуска программы во время компиляции) компилятором.

Постоянное выражение может использоваться для инициализации переменной, помеченной constexpr (referring to the C++11 concept). Такая переменная дает компилятору намек на то, что он может быть оценен во время компиляции (и это может избавить драгоценные циклы выполнения), например.

#include <iostream> 

constexpr int factorial(int n) // Everything here is known at compile time 
{ 
    return n <= 1 ? 1 : (n * factorial(n - 1)); 
} 

int main(void) 
{ 
    constexpr int f = factorial(4); // 4 is also known at compile time 
    std::cout << f << std::endl; 
    return 0; 
} 

Example

Если вы не обеспечивают постоянное выражение, нет никакого способа, компилятор может реально сделать всю эту работу во время компиляции:

#include <iostream> 

constexpr int factorial(int n) // Everything here is known at compile time 
{ 
    return n <= 1 ? 1 : (n * factorial(n - 1)); 
} 

int main(void) 
{ 
    int i; 
    std::cin >> i; 
    const int f = factorial(i); // I really can't guess this at compile time.. 
           // thus it can't be marked with constexpr 
    std::cout << f << std::endl; 
    return 0; 
} 

Example

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

+0

@pieroborrelli вам нужно лучше изучить C++, я не писал сложных вещей. Простыми словами: если вам нужна функция, которая что-то вычисляет, и вы знаете, что это можно сделать во время компиляции вместо времени выполнения, C++ может помочь вам сделать это и предварительно вычислить значение этой функции. Наличие результата сразу во время компиляции более эффективно, чем вычислять его при запуске программы. ** Я не могу объяснить это проще, чем это ** –

+0

@ Марко А. Хорошо, спасибо, только один вопрос: когда я использую переменную, инициализированную без обозначения constexpr, это переменная, созданная в памяти во время выполнения? –

+0

@pieroborrelli Это зависит от типа хранилища переменной (например, static, automatic и т. Д.), Но не может отображаться в выражении constexpr. –

Смежные вопросы