首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Constexpr变量评价

Constexpr变量评价
EN

Stack Overflow用户
提问于 2015-07-12 23:47:52
回答 1查看 439关注 0票数 3

这是我的代码,我需要澄清正在发生的事情:

代码语言:javascript
复制
constexpr int funct(int x){
    return x + 1;
}


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

constexpr允许编译时间计算,根据我上面的代码,由于funct被声明为constexpr,所以如果参数是常量或参数本身,则允许进行编译时间计算。

我所困惑的部分在于这部分,int x。由于它没有被声明为constexpr,这是否意味着int x将在运行时获得该值?这是否意味着将其声明为constexpr int x将意味着int将在编译时得到与int x不同的值?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-13 00:34:48

这取决于所讨论的编译器的许多方面。什么类型的优化可能发生,等等,但是,constexpr本质上并不支持编译时计算。

取此代码:

代码语言:javascript
复制
#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盒子,实际上,这仍然是一个电话,两者计数的编译时所谓的“测试”。我用的台词是

代码语言:javascript
复制
g++ -std=c++11 -Wall -g  -c main.cpp -o obj/Debug/main.o
g++  -o bin/Debug/TestProject obj/Debug/main.o   

因此,在上面的代码中,会产生以下机器代码:

代码语言:javascript
复制
0x40061c    mov    edi,0x5
0x400621    call   0x400659 <test(int)>
0x400626    mov    esi,eax
0x400628    mov    edi,0x4006f4
0x40062d    mov    eax,0x0
0x400632    call   0x4004f0 <printf@plt>
0x400637    mov    edi,0xa
0x40063c    call   0x400659 <test(int)>
0x400641    mov    esi,eax
0x400643    mov    edi,0x4006fd
0x400648    mov    eax,0x0
0x40064d    call   0x4004f0 <printf@plt>

其中用于“测试”的asm块是:

代码语言:javascript
复制
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是如何产生那个代码没有任何影响。即使这样做,仍然会得到运行时计算:

代码语言:javascript
复制
int value = test(30);
printf("Value: %u\n", value);

这会产生这样的结果(由于添加了更多的代码,测试地址略有改变):

代码语言:javascript
复制
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 <printf@plt>

但是,如果将值本身声明为constexpr,则会产生预期的结果:

代码语言:javascript
复制
constexpr int value = test(30);
printf("Value: %u\n", value);

相关代码是:

代码语言:javascript
复制
0x400623    mov    esi,0x37
0x400628    mov    edi,0x400714
0x40062d    mov    eax,0x0
0x400632    call   0x4004f0 <printf@plt>

因此,从本质上说,如果您只是简单地将方法声明加在constexpr前面,那么就不能保证编译时计算。您还需要将变量声明为constexpr并将其赋值给它。执行这样的声明实际上需要编译器对结果进行静态评估。GCC实际上对你大喊大叫,如果你试图这样做,而“测试”并没有被宣布为警官:

main.cpp|10|error:调用非constexpr函数‘int(Int)’x

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31373689

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档