最短的可以造成 crash 且編譯器無法優化掉的 C++ 代碼是什麼?

測試 crash analytics 的工具,突然想到 C++ 中最短的、不可優化的且能穩定造成 crash 的代碼是什麼?


1. Dereferencing null pointer 是比較常見的崩潰方式(C++標準中是未定義行為,是否崩潰是平台相關):

int main() {
return *(int*)0;
}

如果怕造成 warning,可用:

int* p; // 全局變數自動清零,但因為是non-static,其他函數可以修改,??
int main() {
return *p; // ??使這行代碼無法在編譯期判斷p的值
}

2. 一些平台在除零時會崩潰(從語言標準來說這是未定義行為,可能不崩):

int z; // 和上面的 p 同理
int main() {
return 1 / z;
}

3. 拋出沒有處理的異常:

int main() {
throw 0;
}

4. 遞歸導致的 stack overflow崩潰:

int main() {
return main();
}

更新:上面調用main()在C++標準中不容許,但多數能編譯。另一種寫法:

int f(int x) { return x + f(0); }
int main() {
return f(0);
}

用 clang -O3 也會崩潰(更trivial的情況clang不會崩潰)。

5. 調用位於 0 的函數指針,通常會做成 illegal instruction 的崩潰(平台相關):

int main() {
return ((int(*)())0)();
}

6. clang 能編譯鏈接以下程序並造成崩潰,可能是最短的崩潰程序:

int main;

.


長度為0。

樓上各位給出的代碼都十分精彩,但假如就「能過編譯並生成可執行文件,並且可執行文件運行時會導致崩潰的代碼」這一定義來說,最短的C++代碼的長度是0,即空的".cc"文件。

操作過程如下(以linux命令行為例):

首先,創建空的".cc"文件。

$ touch empty.cc

之後用g++僅進行編譯與彙編,而不進行鏈接。

$ g++ -c empty.cc

再用ld命令手動進行鏈接。

$ ld empty.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400078

最後運行可執行文件,得到Segmentation fault。

$ ./a.out
Segmentation fault (core dumped)

註:以上均為linux命令行,實際C++代碼長度為0。


redis中 _redisPanic是這樣寫的

*((char*)-1) = "x";


//crash.c

main;

clang crash.c

./a.out

main不是保留字但是是硬編碼的程序入口


直接throw個異常 當然也可以直接用系統級別的函數拋出個異常 這只是我能想到最簡單的方法


printf("%*c%hn",10,0,printf);


感覺題主是打算用這代碼搞點兒什麼大新聞嗎?


只要半個燙


Abort()


assert(0);


main;


推薦閱讀:

在c中為什麼經常看到for( ; ; )這樣的語句,而不直接用while(1)?
為什麼大多數的C++的開源庫都喜歡自己實現一個string?
C++或QT項目如何進行CI(Continuous Integration)?
Clang 解析錯誤和報錯的機制?
Visual studio中的「添加引用」是什麼意思?

TAG:編程 | 程序 | C | 編譯器 |