简体   繁体   English

c ++中的条件运算符错误?

[英]conditional operator bug in c++?

These demo functions should not be infinite loops in gcc because the conditional operator should only evaluate the active part. 这些演示函数不应该是gcc中的无限循环,因为条件运算符应该只评估活动部分。

They compile correctly in visual studio 2015 but give infinite recursion error compile error in g++ 6.3. 它们在visual studio 2015中正确编译,但在g ++ 6.3中给出了无限递归错误编译错误。 What am I missing? 我错过了什么?

template <int n>
constexpr int infinite_loop_error(){
   return (n)  ? infinite_loop_error<n - 1>() : 0;
}

template <int n> 
constexpr int infinite_loop_error_2(){
   if (n) return infinite_loop_error_2<n - 1>(); 
   else   return 0;
}

void main() {
  infinite_loop_error<3>();
  infinite_loop_error_2<3>();
}

This is a bug in MSVC, your program shouldn't compile. 这是MSVC中的一个错误,您的程序不应该编译。 You are mixing up runtime recursion and compile-time recursion. 您正在混合运行时递归和编译时递归。

While the program should only evaluate one hand of the ternary expression at runtime , the compiler still needs to generate code for both hands of the ternary expression (and for both branches of the if condition). 虽然程序应该只在运行时评估三元表达式的一只手,但编译器仍然需要为三元表达式的双手(以及if条件的两个分支)生成代码。 Your program fails during code generation because the compiler can't find a point where it can stop. 您的程序在代码生成期间失败,因为编译器找不到它可以停止的点。 MSVC "succeeds" because it applies optimizations too early, infringing on the as-if rule. MSVC“成功”,因为它过早地应用优化,侵犯了as-if规则。

You need to use a template specialization as a stopping condition : 您需要使用模板专门化作为停止条件

template <int n>
constexpr int infinite_loop_error(){
   return (n)  ? infinite_loop_error<n - 1>() : 0;
}

template <>
constexpr int infinite_loop_error<0>(){
    return 0;
}

template <int n> 
constexpr int infinite_loop_error_2(){
   if (n) return infinite_loop_error_2<n - 1>(); 
   else   return 0;
}

template <> 
constexpr int infinite_loop_error_2<0>(){
   return 0;
}

int main() {
  infinite_loop_error<3>();
  infinite_loop_error_2<3>();
}

Instead of instantiating infinite_loop_error<0> from the definition that will make it recurse further, the compiler uses the definition that you provide for it and compile-time recursion correctly stops. 编译器使用您为其提供的定义而不是从定义中实例化infinite_loop_error<0> ,而编译时递归正确停止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM