2 回答
TA贡献1995条经验 获得超2个赞
在C ++ 14中,这显然是不允许的,尽管在2011
这种情况下似乎是明确允许的。目前还不清楚C ++ 11 是否属于as-if规则,我不相信它会改变,因为它会改变可观察的行为,但这一点在我在下面引用的问题中并未澄清。
细节
这个问题的答案随着2013年LWG问题的演变而变化,该问题开始于:
假设特定函数未在标准中标记为constexpr,但在某些特定实现中,可以在constexpr约束内编写它。如果实施者标记constexpr这样的功能,是违反标准还是符合标准的扩展?
在C ++ 11中,不清楚as-if规则是否允许这样做,但是orignal提议一旦被接受就明确允许它,我们可以在下面的gcc bug报告中看到我引用,这是gcc做出的假设球队。
允许这种转变的共识在2012年发生了变化并且提案发生了变化,而在C ++ 14中,这是一个不合规的扩展。这反映在草案C ++ 14标准部分17.6.5.6
[constexpr.functions]中,该部分说:
[...]实现不得将任何标准库函数签名声明为constexpr,除非明确要求它。[...]
虽然严格阅读这个内容似乎留下了一些回避处理内置因素的余地,好像它是一个constexpr我们可以从问题中的以下引用中看出,目的是防止实现中的分歧,因为相同的代码可能会产生不同的行为使用SFINAE时(强调我的):
当向完全委员会提交对WP状态的投票时表达了一些担忧,即在没有充分考虑图书馆实施不同的后果的情况下解决了这个问题,因为用户可能会使用SFINAE来观察其他相同代码的不同行为。
我们可以从gcc bug报告[C ++ 0x] sinh vs asinh vs constexpr看到该团队依赖早先提出的LWG 2013决议,其中说:
[...]此外,如果该函数的定义满足必要的约束,则实现可以声明任何函数为constexpr [...]
在确定是否允许在严格一致性模式下对数学函数进行此更改时。
据我所知,如果我们在严格的一致性模式下收到警告,即使用-std=c++11 -pedantic
或者在此模式下被禁用,这将符合要求。
请注意,我在错误报告中添加了一条评论,解释说自从此问题最初解决后,解决方案已更改。
Jonathan Wakely 在另一个问题中指出了一个更近期的讨论,似乎可能会重新打开gcc bug报告来解决这个一致性问题。
本质上怎么样?
编译器内在函数不在标准范围内,因此,据我所知,它们应该免于此规则,因此使用:
static constexpr double a = __builtin_cos(3.);
应该被允许。这个问题出现在错误报告中,DanielKrügler的意见是:
[...]库函数和其他内在函数可能被视为异常,因为它们不需要通过常规语言规则“解释”。
TA贡献1856条经验 获得超5个赞
我不认为谈论编译器内在函数是有帮助的。所有以名称开头的名称__
都保留用于实现,并且实现定义了它们的语义。对于特定于实现的函数的语义是完全合理的,无论它们是否是内在的,都被定义为constexpr
纯粹由实现者自行决定。
- 2 回答
- 0 关注
- 685 浏览
添加回答
举报