作業環境: 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)
沒有留言:
張貼留言