Constexpr变量评估 [英] Constexpr variable evaluation

查看:166
本文介绍了Constexpr变量评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里是我的代码,我需要澄清发生了什么:

Here is my code and I need clarification on what's happening:

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


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

constexpr 允许编译时计算,并且基于我上面的代码,因为 funct 被声明为 constexpr 编译时计算如果参数是常量或constexpr本身。

constexpr's allows compile time calculation, and based on my code above, since funct is declared as constexpr, it is allowed to do compile time calculations if the arguments are constants or constexpr's themselves.

我困惑的部分在这一部分, int x 。因为它不被声明为 constexpr ,是否意味着 int x 将在运行时获得值?这意味着声明为 constexpr int x 意味着int x将在编译时获得不同于 int x

The part that I am confused with lies in this part, the int x. Since it is not declared as constexpr, would it mean that int x will get the value at runtime? Does that mean that declaring it to be constexpr int x will mean that int x will get the value at compile time unlike int x ?

推荐答案

这取决于许多计数的编译器。

It depends on the compiler in question on many counts. What sorts of optimizations that may take place, etc. However, constexpr does not inherently enable compile-time calculations.

使用以下代码:

#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));
}

在我的x86_64 Gentoo框上的GCC 4.8.4下,调用两个计数到所谓的编译时测试。我使用的行是

Under GCC 4.8.4 on my x86_64 Gentoo box, that actually still makes a call on both counts to the supposedly compile-time "test". The lines I used were

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

在上面的代码中,生成以下机器码:

So on the code above, that produces the following machine code:

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>

test的asm块为:

Where the asm block for "test" is:

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


b $ b

所以,你可以看到在这种情况下,似乎对GCC如何生成该代码几乎没有影响。即使你这样做,你仍然会得到运行时计算:

So, as you can see in that situation, it seems to hold pretty much no effect over how GCC produced that code. Even if you do this, you will still get runtime calculations:

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

在哪里产生这个(由于添加一些更多的代码,测试的地址稍微改变):



Where that produces this (the address of test changed slightly due to adding some more code):

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>

但是,如果您声明值本身,它会产生预期结果 as constexpr:

It does, however, produce the expected result if you declare the value itself as 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 <printf@plt>

因此,你不能保证编译时计算, constexpr。你还需要声明一个变量为constexpr并赋值给它。执行这样的声明将实际上需要编译器静态评估结果。如果你尝试这样做,并且test没有声明为constexpr,GCC实际上会大喊:

So essentially, you're not guaranteed a compile-time calculation if you simply prepend the method declaration with constexpr. You also need to declare your a variable as constexpr and assign to it. Doing such a declaration will actually require the compiler to statically evaluate the result. GCC actually yells at you if you try to do this and "test" isn't declared constexpr:


main.cpp | 10 | :调用非常量表达式函数'int test(int)'|

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

这篇关于Constexpr变量评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆