これは、C言語の仕様なのか?

リカルドです。

 CS+で、C言語の実験をしてみました。
 次のプログラムの A = Sub4(5) の所で返り値が有りません。
 しかしコンパイル・エラーにはなりません。
 CS+のチェックが甘いのか、C言語の仕様なのか、どちらなんでしょう。


int Sub4(int D) ;

int main(void)
{
int A ;
A = Sub4(5) ; // 「int」の返り値が無くてもエラーにはならない
}

int Sub4(int D)
{
}

  • 仕様というか歴史的事情というか。

    ごく初期の C (K&R 第1版の頃) には void ってのはありませんでした。なので **返却値がないこと** をソースコード上明記することはできませんでした。そういう状況では下記のようなソースコードを書いていました。

    hoge() { /* 何か処理 */} /* 返却値が無いことを K&R 1の頃はこう書いた */

    この記述はその当時としては 100% 妥当なコードであり、これに対してコンパイルエラーや警告は出さないようコンパイラのほうが実装されていました。(コンパイラは int を返す関数 hoge() と解釈しますが return していないことに対して警告を出さないよう実装されていました)

    現代 C コンパイラにおいても当時のソースコードがエラー無くコンパイルできるよう配慮がされています。 ccrx や Microsoft Visual C++ では、上記 hoge() に対して一切のエラー・警告を発しないようになっています。

    int fuga() { /* return を書き忘れた */ }

    に対しては ccrx/cl ともに「 return がない」警告が出ます(エラーにはなりません)リカルドさんのとこでも出ているはずです。見逃していませんか?

    ----

    C++ ではそのような古いソースコードをコンパイルできるような配慮よりバグが出ないほうがよいという判断により return すべき関数で return がない(あるいは return; のみ)ってのは診断対象になっている=コンパイルエラーになることになっています。

  • GCCでも似たような議論がされていますね。
    警告を出して当然、という結論にはなっていないようです。GCCでは-Wunusedで警告を出させることもできますが、それはそれでうるさそうです。
    No warning for main() without a return statement with -std=c99
    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53232

  • cacao99 さん、リカルドです。

    早速の回答有難う御座います。

    > int fuga() { /* return を書き忘れた */ }
    > に対しては ccrx/cl ともに「 return がない」警告が出ます(エラーにはなりません)リカルドさんのとこでも出ているはずです。見逃していませんか?

     良く分かりました。エラーレベルでは無く、警告レベルなのですね。「C言語のコンパイラは、そのような仕様だ」と分かりました。
     次のメッセージが有りました。

    W0520940:Missing return statement at end of non-void function "Sub4"

    W0520940 をインターネットで調べると、次のメッセージが有りました。

      void でない関数"名前"に return 文がありません。

  • Okra さん

    回答有難う御座います。