作業環境:
Linux li475-173 3.5.2-linode45 #1 SMP Wed Aug 15 14:10:55 EDT 2012 i686 GNU/Linux
gcc version 4.4.5 (Debian 4.4.5-8)
-
test code: (已經簡化到最少)
#include <stdio.h>
#include <string.h>
int main(void)
{
char *na = NULL;
char *nb = NULL;
int ret = 1234;
strcmp(NULL, NULL); // case 1
strcmp(na, nb); // case 2
ret = strcmp(NULL, NULL); // case 3
ret = strcmp(na, NULL); // case 4
ret = strcmp(NULL, nb); // case 5
ret = strcmp(na, nb); // case 6
printf("%d\n", ret);
return 0;
}
case 1-6 只會使用其中一行進行編譯(gcc test.c), 不加其他編譯參數.
若加上 -Wall 可以看到類似這樣的警告訊息:
warning: null argument where non-null required
-
case 1 2 3 可以執行無誤, case 4 5 6 都會噴 Segmentation fault
-rwxr-xr-x 1 slzzp admin 4520 Jul 1 20:35 a.out.1
-rwxr-xr-x 1 slzzp admin 4520 Jul 1 20:36 a.out.2
-rwxr-xr-x 1 slzzp admin 4520 Jul 1 20:36 a.out.3
-rwxr-xr-x 1 slzzp admin 4622 Jul 1 20:36 a.out.4
-rwxr-xr-x 1 slzzp admin 4622 Jul 1 20:36 a.out.5
-rwxr-xr-x 1 slzzp admin 4622 Jul 1 20:36 a.out.6
b3b2d33b3f5dca1b9df14eed6056d216 a.out.1
b3b2d33b3f5dca1b9df14eed6056d216 a.out.2
015e405413b165b7539f3dfd6f0601f2 a.out.3
2e64c7055fae7e606412ef2adede6d87 a.out.4
8b620ac644f8a18e5cbb953d19b8ede5 a.out.5
d8987fb39dbb7046b772cb86a11f149e a.out.6
故意把 case 1 跟 case 2 多複製幾行, 編譯後的 a.out 檔案大小跟 md5
都相同, case 3 的執行結果 ret 是 0, 應該都被自動 -O 過了.
所以 case 1 2 3 根本沒進去 strcmp 執行過... oroz
補充: ret 是 0 表示 strcmp() 的結果是 TRUE, 理論上來說 NULL 跟 NULL
相比的確是一樣的沒錯.
那 case 4 5 6 的狀況呢...
查了幾下之後, 得到這個結論:
Passing a null pointer to strcmp() results in undefined behaviour.
Don't do it.
--
嗚嗚, libc/strcmp 沒有做防呆檢查...
只好再想想 test unit / test process 要怎麼改了... T_T
2013年7月1日 星期一
strcmp() 傳 NULL 進去的神秘現象...
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言