4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

voidでない関数は値を返す必要がある

Last updated at Posted at 2021-07-17

まあ、当たり前のことですが…

#include <stdio.h>
#include <stdlib.h>
__attribute__((noinline)) int func(int n){
for(volatile int i=0;i<n;i++)puts("hello world");
fflush(stdout);
getenv("PATH");
}
int main(){
func(3);
}

これをgccに食わせると、no return statement in function returning non-void警告が発生します。
この警告に関して、返値を呼び出し側で使わなければ動作に影響はないと思っている人は多いと思います(私もその一人でした)。
しかし実際には、以下のようになります12

処理系 func呼び出し結果
gcc 返値不定
g++-6以下 0が返る
g++-7 返値不定
g++-8以上 segmentation fault
clang 返値不定
clang++ segmentation fault
icc 返値不定
icpc 返値不定
icx 返値不定
icpx 返値不定
msvc (値を返さないのはそもそも警告ではなくコンパイルエラー)

g++-8以上およびclang++3では スタックポインタを復元するアセンブリもretアセンブリも出力されませんでした。 segvまっしぐらです4
今まで気づかなかったのが不思議です。。

  1. https://gcc.godbolt.org/ で確認しました。すごく便利なサイトですね。

  2. 最適化ありの場合です。

  3. CとしてコンパイルしたときとC++としてコンパイルしたときの挙動が違う…。

  4. しかもこれ系はgdbで正しいスタックトレースが取得できなくなるので極めてたちが悪い。

4
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?