gcc 4.6 编译器的奇怪行为

Posted

技术标签:

【中文标题】gcc 4.6 编译器的奇怪行为【英文标题】:Weird behaviour of gcc 4.6 compiler 【发布时间】:2011-10-14 07:22:46 【问题描述】:

这段代码:

template<class Int_T, long long Min, unsigned long long Max>
class Int_Core

static_assert(Check_Range<Minimum>::check(Min,std::numeric_limits<Int_T>::min()),"INCORRECT Min range.");
static_assert(Check_Range<Maximum>::check(Max,std::numeric_limits<Int_T>::max()),"INCORRECT Max range.");

我得到的错误是在第二个 static_assert 告诉我已经使用了非常量表达式。但是 如果我在第二个断言中将 'Max' 更改为 'Min',它确实可以毫无问题地编译。怎么回事? 错误:错误:静态断言的非常量条件

那些是辅助类/fncs:

//this is Int_Core.h file

struct Minimum
/*eb*/;
struct Maximum
/*eb*/;

/**Checks if given range is within boundary*/
template<class Range>
struct Check_Range;

template<>
struct Check_Range<Minimum>

template<class Value,class Limit>
static constexpr bool check(Value val,Limit limit)

    return greater_than_or_equal_with(val,limit);

;

template<>
struct Check_Range<Maximum>

template<class Value,class Limit>
static constexpr bool check(Value val,Limit limit)

    return greater_than_or_equal_with(val,limit);

;

constexpr bool greater_than(long long signed_,unsigned long long unsigned_)

//   unsigned long long mask = 0x8000000000000000LL;
//   bool is_negative = signed_ & mask;
//   if (is_negative)
//   
//
//       return false;
//   
//   else
//   
//      return (signed_ > unsigned_);
//   
//
   return (signed_ & 0x8000000000000000LL) ? false : (signed_ > unsigned_);


constexpr bool equal_with(long long signed_,unsigned long long unsigned_)

//   unsigned long long mask = 0x8000000000000000LL;
//   bool is_negative = signed_ & mask;
//   if (is_negative)
//   
//
//       return false;
//   
//   else
//   
//      return (signed_ == unsigned_);
//   
//This line is == to the commented code above (constexpr must have just return statement)
   return (signed_ & 0x8000000000000000LL) ? false : (signed_ == unsigned_);


constexpr bool greater_than_or_equal_with(long long signed_,unsigned long long unsigned_)

    return (greater_than(signed_,unsigned_) || equal_with(signed_,unsigned_));

更新:

#include "Int_Core.h"
    int main()
    
       Int_Core<unsigned char,1,-50> a;
    

【问题讨论】:

你能提供任何测试用例吗? @Griwes 我还没有任何测试用例。只需粘贴并尝试编译它。我会用 main fnc 更新我的帖子。 拥有一个可以根据实例化作为有符号或无符号整数的类模板会增加复杂性。当您将这两种情况分开时,事情会变得简单得多。可能无论如何您都不需要未签名的变体。 @KerrekSB operator @KerrekSB 使用 type_traits 没关系 - 它(运算符 【参考方案1】:

这是gcc 4.6.0的编译器bug,gcc 4.6.1正确触发了static_assert。

【讨论】:

@smallB:当您想使用最前沿的功能/技术时就是这样。 我没关系;)总是有事可做。

以上是关于gcc 4.6 编译器的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

gcc 内联汇编行为异常

__unused标记行为/用法(GCC与Objective-C)

为啥我不需要在 gcc 4.6 中包含 STL 标头?

Ubuntu下两个gcc版本切换

g++-8 和更早版本之间的奇怪行为

编译安装 gcc 4.9并验证使用