测试了一个简单的utf8 strlen函数,并对树干clang完全消除它感到非常惊讶(gcc没有):
static int strlenutf8(const char* s)
{
int i = 0, l = 0;
while (s[i])
{
if ((s[i] & 0xc0) != 0x80) l++;
l++;
}
return j;
}
int main()
{
return strlenutf8("bla");
}clang++ -O3 -S -fverbose asm:
main: # @main
.cfi_startproc
# BB#0: # %entry
movl $3, %eax
ret这就像D的编译时函数评估。这在C++中合法吗?
我的意思是,最终肯定有一个原因,他们发明了那个蹩脚的警察在第一。因为它是严格限制的,所以在这里我甚至不能用它。
发布于 2013-04-24 15:31:50
constexpr仅适用于常量表达式上下文(如模板参数推导),但不能保证在编译时计算constexpr函数。
优化C++程序的黄金法则是as-if规则:
这个国际标准中的语义描述定义了一个参数化的非确定性抽象机器。本国际标准不对一致性实现的结构提出任何要求。特别是,它们不需要复制或模仿抽象机器的结构。相反,遵循实现需要(仅)模仿抽象机器的可观察行为,如下所述。
加上急需的脚注:
这一规定有时被称为“若即若揭”规则,因为执行可以自由地无视本国际标准的任何要求,只要结果是该要求得到遵守,只要能够从程序的可观察到的行为中确定。例如,一个实际的实现不需要评估一个表达式的一部分,如果它可以推断它的值没有被使用,并且没有产生影响程序的可观察行为的副作用。
对于一个主要的但是:复制构造函数具有副作用(例如,它们增加一个名为“count变量或等效的复制构造函数”)不需要包含在"as-if“中。这包括在12.8/31中
当满足某些条件时,即使对象的复制/移动构造函数和/或析构函数有副作用,也允许实现省略类对象的复制/移动构造。在这种情况下,实现将省略的复制/移动操作的源和目标视为引用同一对象的两种不同方式,并且该对象的销毁发生在如果不进行优化就会销毁两个对象的晚些时候。123在下列情况下允许复制/移动操作(称为复制省略)的省略(可以组合起来消除多个副本):
发布于 2013-04-24 15:30:48
通过在编译时计算表达式,需要一个符合的C++编译器来支持constexpr。as-if规则允许对非constexpr表达式进行编译时评估;由于您的strlenutf8函数没有(可见的)副作用,所以允许编译器对其进行编辑。
发布于 2013-04-24 16:02:48
您将如何编写符合标准的C++程序来检测这种优化?如果您想不出一种方法,那么优化是可以的(好的,好的,如果没有的话)。并不仅仅因为您可能查看生成的代码就要求编译器执行低效率的操作。
https://stackoverflow.com/questions/16195924
复制相似问题