2015-07-12 1 views
3

Вот мой код, и мне нужно разъяснить, что происходит:Constexpr переменная оценка

constexpr int funct(int x){ 
    return x + 1; 
} 


int main(){ 
    int x = funct(10); 
    return 0; 
} 

constexpr «s позволяет составить расчет времени, и, основываясь на моем коде выше, так как funct объявлен как constexpr, допускается делать вычисления времени компиляции, если аргументы являются константами или самими constexpr.

Часть, которую я путаю с ложью в этой части, int x. Так как он не объявлен как constexpr, значит ли это, что int x получит значение во время выполнения? Означает ли это, что объявление constexpr int x будет означать, что int x получит значение во время компиляции в отличие от int x?

+1

Какая разница? Или, как бы вы могли даже сказать разницу? 'x' - локальная переменная, она * имеет * инициализируется во время выполнения. –

+1

Предполагая, что нет оптимизации, да декларация оценивается во время выполнения. Однако компилятору разрешено оптимизировать эту программу до нуля, поскольку она ничего не делает. –

+0

Ahhh я вижу. Так что, если это 'int x', то это наверняка будет во время выполнения, а' constexpr' будет во время компиляции? –

ответ

4

Это зависит от компилятора, о котором идет речь, по многим вопросам. Какие виды оптимизаций могут иметь место и т. Д. Однако constexpr по своей сути не позволяет вычислять время компиляции.

Возьмите этот код:

#include <cstdio> 

constexpr int test(int in) 
{ 
    return in + 25; 
} 

int main(int argc, char* argv[]) 
{ 
    printf("Test: %u\n", test(5)); 
    printf("Two: %u\n", test(10)); 
} 

Под GCC 4.8.4 на моем x86_64 Gentoo поле, что на самом деле до сих пор делает вызов по обоим пунктам, чтобы якобы во время компиляции «тест». Линии, которые я использовал были

g++ -std=c++11 -Wall -g -c main.cpp -o obj/Debug/main.o 
g++ -o bin/Debug/TestProject obj/Debug/main.o 

Так на приведенном выше коде, который производит следующий машинный код:

0x40061c mov edi,0x5 
0x400621 call 0x400659 <test(int)> 
0x400626 mov esi,eax 
0x400628 mov edi,0x4006f4 
0x40062d mov eax,0x0 
0x400632 call 0x4004f0 <[email protected]> 
0x400637 mov edi,0xa 
0x40063c call 0x400659 <test(int)> 
0x400641 mov esi,eax 
0x400643 mov edi,0x4006fd 
0x400648 mov eax,0x0 
0x40064d call 0x4004f0 <[email protected]> 

Где ASM блок для "Тест":

0x400659 push rbp 
0x40065a mov rbp,rsp 
0x40065d mov DWORD PTR [rbp-0x4],edi 
0x400660 mov eax,DWORD PTR [rbp-0x4] 
0x400663 add eax,0x19 
0x400666 pop rbp 
0x400667 ret 

Так , как вы можете видеть в этой ситуации, похоже, что он почти не влияет на то, как GCC подготовил этот код. Даже если вы сделаете это, вы все равно получите вычисления времени выполнения:

int value = test(30); 
printf("Value: %u\n", value); 

Где, который производит этот (адрес теста немного изменился за счет добавления еще немного кода):

0x40061c mov edi,0x1e 
0x400621 call 0x40067a <test(int)> 
0x400626 mov DWORD PTR [rbp-0x4],eax 
0x400629 mov eax,DWORD PTR [rbp-0x4] 
0x40062c mov esi,eax 
0x40062e mov edi,0x400714 
0x400633 mov eax,0x0 
0x400638 call 0x4004f0 <[email protected]> 

Это делает, однако , производят ожидаемый результат, если вы объявите значение сама в constexpr:

constexpr int value = test(30); 
printf("Value: %u\n", value); 

и связанный с ним код:

0x400623 mov esi,0x37 
0x400628 mov edi,0x400714 
0x40062d mov eax,0x0 
0x400632 call 0x4004f0 <[email protected]> 

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

main.cpp|10|error: call to non-constexpr function ‘int test(int)’|

+0

Я вижу, спасибо за подробное объяснение. Я буду изучать это. –

+0

Добро пожаловать. – Ragora

+0

Просто вопрос, если я создаю конструктор constexpr, они автоматически constexpr? –

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

  • Нет связанных вопросов^_^