我这里有这个小片段:
#include <string.h>
#include <stdio.h>
int main(void) {
char b[128];
strcpy(b, "four");
if(strcmp(b, "seven") == 0) {/* Line 9 */
printf("buffer 'b' contains \"%s\"\n", b);
}
else if(strcmp(b, "four") == 0) {
printf("buffer 'b' contains \"%s\"\n", b);
}
return 0;
}
如果我使用 Clang 版本“7.0.0-3~ubuntu0.18.04.1 (tags/RELEASE_700/final)”编译它,即使使用 -O3
也很好。如果我对 Clang 版本“8.0.0-3~ubuntu18.04.2 (tags/RELEASE_800/final)”或更高版本(也检查了 9.0.0 版)执行相同的操作,除了 -O0
Valgrind 告诉我< /p>
==17979== Memcheck, a memory error detector
==17979== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==17979== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==17979== Command: ./glibc_strcmp_x86_64_sse_4_2_bug
==17979==
==17979== Conditional jump or move depends on uninitialised value(s)
==17979== at 0x400540: main (glibc_strcmp_x86_64_sse_4_2_bug.c:9)
==17979== Uninitialised value was created by a stack allocation
==17979== at 0x400520: main (glibc_strcmp_x86_64_sse_4_2_bug.c:4)
==17979==
buffer 'b' contains "four"
==17979==
==17979== HEAP SUMMARY:
==17979== in use at exit: 0 bytes in 0 blocks
==17979== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
==17979==
==17979== All heap blocks were freed -- no leaks are possible
==17979==
==17979== For counts of detected and suppressed errors, rerun with: -v
==17979== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
如果我用例如:char b[128] = {0};
初始化缓冲区,当然,没有任何抱怨。或者,如果我使用本地版本的 strcmp
。
分别转储每个 -O1
和 -O0
的程序集输出表明,Clang-8 的优化优化了所有出现的 strcmp
(和 strcpy
)。 Clang-7 没有这样做,它调用了所有的函数。
但是这该怪谁呢?这是 Clang > 7 中的错误吗?或者我的假设是错误的,即 strcmp
,即使优化掉了,一旦任何一个输入达到 \0
就应该停止?