加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – clang 3.3和constexpr约束

发布时间:2020-12-16 05:05:00 所属栏目:百科 来源:网络整理
导读:我正在用clang 3.3编译一些代码,似乎可以用 gcc 4.8编译好: 原始代码是: template std::size_t N struct helper { typedef void type; };template struct helper64 { typedef int64_t type; };template struct helper32 { typedef int32_t type; };templat
我正在用clang 3.3编译一些代码,似乎可以用 gcc 4.8编译好:

原始代码是:

template <std::size_t N> struct helper { typedef void type; };
template <> struct helper<64> { typedef int64_t type; };
template <> struct helper<32> { typedef int32_t type; };
template <> struct helper<16> { typedef int16_t type; };
template <> struct helper<8>  { typedef int8_t type; };

template <std::size_t I,std::size_t F>
struct test
{
    typedef typename helper<I+F>::type value_type; 
    static constexpr std::size_t frac_mask = ~((~value_type(0)) << F);
};

在clang中,如果我尝试声明测试< 16,16>或测试< 8,0>我收到错误:

test.cpp:41:34: error: constexpr variable ‘frac_mask’ must be initialized by a constant expression

06001

如果我将代码转换为:

template <std::size_t I,std::size_t F>
struct test
{
    typedef typename helper<I+F>::type value_type; 
    typedef typename std::make_unsigned<value_type>::type mask_type;

    static constexpr mask_type frac_mask = ~((~mask_type(0)) << F);
};

它在大多数情况下编译(I,F的值),但如果我声明测试< 8,0>,我得到错误:

test.cpp:23:36: error: constexpr variable ‘frac_mask’ must be initialized by a constant expression

test.cpp:66:15: note: in instantiation of template class ‘test<8,0>’ requested here

test.cpp:23:66: note: left shift of negative value -1

06003

我的问题是 – 在constexpr的规范方面,我是否违反了一些规则?此外,对于最后一个错误 – 掩码类型是无符号的 – 这是一个编译器问题,它认为我正在转移负值或我误读代码?

解决方法

在第一种情况下,您将导致签名溢出. C 11 5.19 / 2中列出的表达式不是常量表达式的条件之一是它涉及

a result that is not mathematically defined or not in the range of representable values for its type

通过使用无符号类型(定义为使用模运算),结果保持在范围内.据推测,GCC对这一规则的严格程度不如Clang.

在最后一种情况下,无符号8位类型被提升为int,而不是无符号类型,因此您再次获得有符号溢出.您可以通过在否定之后转换回无符号类型来解决此问题:

static constexpr mask_type frac_mask = ~(mask_type(~mask_type(0)) << F);

虽然我对此不太确定,并且没有要测试的Clang安装.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读