C++ 编译器决定调用函数“POW”,而不是在编译时对其求值。为什么?

C++ 编译器决定调用函数“POW”,而不是在编译时对其求值。为什么?,c++,runtime,c++14,constexpr,C++,Runtime,C++14,Constexpr,我从by那里得到了下面的片段 #包括 模板 康斯特普基地战俘(基地基地、世博会) { 返回(世博会!=0)?基地*POW(基地,世博会-1):1; } int main(int argc,字符**argv) { 有两个原因 首先,不能保证在编译时调用constexpr函数。要强制编译器在编译时调用它,必须先将其存储在constexpr变量中,即 constexpr auto pow = POW((unsigned __int64)2, 63); std::cout << pow &l

我从by那里得到了下面的片段

#包括
模板
康斯特普基地战俘(基地基地、世博会)
{
返回(世博会!=0)?基地*POW(基地,世博会-1):1;
}
int main(int argc,字符**argv)
{
有两个原因

首先,不能保证在编译时调用constexpr函数。要强制编译器在编译时调用它,必须先将其存储在constexpr变量中,即

constexpr auto pow = POW((unsigned __int64)2, 63);
std::cout << pow << std::endl;
constexpr auto-pow=pow((unsigned)2,63);

std::cout您期望的是什么?您从未要求编译器在编译时对其进行评估。(您的标题似乎与问题的主体相矛盾…)@marglisse函数
POW
constexpr
,它是用常量表达式调用的。我刚刚编辑了标题。感谢您提醒我注意。查看调试生成代码gen从来都不是很有用。使用const auto value=POW(2,63);强制编译器执行您希望它执行的操作并保证获得满意的结果。了解为什么通过传递(2,-1)而使保证无效:)@hanpassant
了解为什么通过传递(2,-1)而使保证无效
这与使用(2,63)调用函数有什么关系?代码段正常执行,没有任何异常。VS2015编译器似乎只在需要常量表达式的情况下在编译时计算constexpr函数,如上面的示例所示,而不管它是调试还是发布版本。你确定吗?这是反汇编的图像,甚至是using static_assert以确保编译时不会出错:@DeusSum您在链接示例中没有使用VS2015,也没有使用clang或GCC。根据[dcl.constexpr]的说法,这三个编译器在编译时评估函数
POW
,这正是他们应该做的/C++14标准中的9。另请参阅。根据所提到的段落,我必须得出结论,您使用的编译器存在一个错误。“您必须先将其存储在一个constexpr变量中,即。”您在constexpr变量中存储了什么?我不确定我之前怎么没有注意到,但现在它已修复。谢谢。
int main(int argc, char** argv)
{
009418A0  push        ebp  
009418A1  mov         ebp,esp  
009418A3  sub         esp,0C0h  
009418A9  push        ebx  
009418AA  push        esi  
009418AB  push        edi  
009418AC  lea         edi,[ebp-0C0h]  
009418B2  mov         ecx,30h  
009418B7  mov         eax,0CCCCCCCCh  
009418BC  rep stos    dword ptr es:[edi]  
    std::cout << POW((unsigned __int64)2, 63) << std::endl;
009418BE  mov         esi,esp  
009418C0  push        offset std::endl<char,std::char_traits<char> > (0941064h)  
009418C5  push        3Fh  
009418C7  push        0  
009418C9  push        2  
009418CB  call        POW<unsigned __int64,int> (09410FAh)     <<======== 
009418D0  add         esp,0Ch  
009418D3  mov         edi,esp  
009418D5  push        edx  
009418D6  push        eax  
009418D7  mov         ecx,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (094A098h)]  
009418DD  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (094A0ACh)]  
009418E3  cmp         edi,esp  
009418E5  call        __RTC_CheckEsp (0941127h)  
009418EA  mov         ecx,eax  
009418EC  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (094A0B0h)]  
009418F2  cmp         esi,esp  
009418F4  call        __RTC_CheckEsp (0941127h)  
    return 0;
009418F9  xor         eax,eax  
}
constexpr auto pow = POW((unsigned __int64)2, 63);
std::cout << pow << std::endl;