c – clang 3.3和constexpr约束
我正在用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>我收到错误:
如果我将代码转换为: 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>,我得到错误:
我的问题是 – 在constexpr的规范方面,我是否违反了一些规则?此外,对于最后一个错误 – 掩码类型是无符号的 – 这是一个编译器问题,它认为我正在转移负值或我误读代码? 解决方法
在第一种情况下,您将导致签名溢出. C 11 5.19 / 2中列出的表达式不是常量表达式的条件之一是它涉及
通过使用无符号类型(定义为使用模运算),结果保持在范围内.据推测,GCC对这一规则的严格程度不如Clang. 在最后一种情况下,无符号8位类型被提升为int,而不是无符号类型,因此您再次获得有符号溢出.您可以通过在否定之后转换回无符号类型来解决此问题: static constexpr mask_type frac_mask = ~(mask_type(~mask_type(0)) << F); 虽然我对此不太确定,并且没有要测试的Clang安装. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |