现代编译器(或者可能是自C89以来就存在的编译器)是否在条件表达式求值期间用 * 短路求值 * 代码代替下面的情况?
char mystring[32] = "this is a long line";
if((strnlen(mystring, 32)) > 2)
{
return 1;
}
字符串
由于在处理strnlen(...)
的过程中考虑了右操作数,并且当strnlen(...)
内的C字符串的运行长度超过外部条件表达式的右操作数(本例中为2)时,strnlen(...)
会中断?
- 如果我没有预先指定字符串的长度,这会有影响吗?
- 如果我从IF内部表达式中删除括号,这会有影响吗?
- 如果我把操作数和运算符都换成了
<
,会有什么影响吗?
2条答案
按热度按时间ycl3bljg1#
-O3
,并启用了扩展(注意strnlen
是POSIX,不是标准C)。字符串
clang和gcc都将optimize this转换为
mov eax, 1; ret
。这是因为它们知道strnlen
的行为,并且可以替换调用的返回值,而无需在运行时对其进行评估。(在gcc中,这是通过__builtin_strnlen
实现的)。如果
strnlen
函数不是已知的内置函数,但可以内联:型
在这里将optimizes转换为
mov eax, 1
,但gcc发出一个循环。最后,对于一个标记为
pure
的未知 predicate ,它告诉优化器它没有副作用:型
gcc再次emits一个循环; clang发出一些相当笨拙的代码(
ebx
是怎么回事?),尽管如此,它仍然表明它知道f
需要被调用不超过3次,前3个字符的字符代码-它优化了整个字符串:型
不,在这种情况下,C语言只会将缓冲区大小设置为字符串字面量的大小(字符串长度+ 1表示终止符)。
不,优化器运行在不包括这些语法细节的程序表示上。
<
,这会有什么影响吗?几乎可以肯定不是,优化器能够理解它们是等价的。
0lvr5msh2#
它说
strnlen
是一个内置函数,所以gcc可以对strnlen
的语义进行优化。如果你的字符串是常量,它可以优化它(当然这只是一个有趣的事实;它并没有真正帮助你)。
如果编译器事先不知道你的字符串,gcc不会做任何优化。理论上,它可以内联函数并优化结果代码,但实际上,它不会发生。你可以自己实现这样的优化-据我所知,clang有一种方便的语言来描述优化。
我不能说其他编译器。
您可以使用专用的godbolt site来检查这些东西。