Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C/C++関数呼び出しパズル:Cでは動くのにC++ではエラーになる理由

はじめに

CとC++は非常によく似た言語であり、多くのCプログラムはそのままC++でもコンパイル・実行できます。C++にはオブジェクト指向の機能が追加されていますが、基本的な構文の大部分は共通しています。しかし、細かい仕様の違いにより、Cでは問題なく動作するのに、C++ではコンパイルエラーになるコードも存在します。今回は「関数呼び出し」に関する興味深い例を紹介します。

サンプルコード

#include <stdio.h>

void myFunction() {
    printf("Function called\n");
}

int main() {
    myFunction();
    myFunction(2);
}

実行結果(Cコンパイラの場合)

Function called
Function called

このプログラムはCコンパイラではコンパイルして実行でき、上記のように出力されます。ところが、同じコードをC++としてコンパイルすると、コンパイル時点で次のようなエラーが発生します。

error: too many arguments to function 'void myFunction()'

つまり「引数が多すぎる」と指摘され、ビルドに失敗してしまうのです。

なぜCでは動いて、C++ではエラーになるのか?

ポイントは、関数宣言における空の引数リスト「()」の意味の違いにあります。

  • C言語の場合: 従来のC規格では、引数リストを「()」と空のまま書くと「引数の個数や型は未指定」という意味になりました(いわゆるK&Rスタイルの名残です)。そのため、myFunction(2) のように引数を渡してもコンパイルエラーにはなりません。
  • C++の場合: 空の「()」は厳密に「引数を一切受け取らない」ことを意味します。したがって、引数なしの関数に 2 を渡すと、コンパイラが「引数が多すぎる」と判断し、エラーとなります。

補足として、最新のC規格(C23)では、C++と同様に空の括弧「()」が「引数なし」を意味するように変更されました。そのため、C23準拠の新しいコンパイラでは、このコードはC言語としてもエラーになる点に注意が必要です。

まとめ

CとC++は高い互換性を持つ一方で、関数宣言の引数リストの扱いなど、細かな仕様の違いがあります。このような落とし穴を避け、移植性の高いコードを書くためには、引数を受け取らない関数は void myFunction(void) のように明示的に void を指定するのが安全で推奨される書き方です。

  1. C/C++のmbsrtowcs()関数とは?構文・パラメータ・戻り値と実例を解説

    本記事では、C++ STLに含まれるstd::mbsrtowcs()関数の仕組み、構文、および具体的な使用例について詳しく解説します。 std::mbsrtowcs()とは? std::mbsrtowcs()は、C++ STLに組み込まれている関数で、<cwchar>ヘッダーファイル内で定義されています。関数名のmbsrtowcs()は「multibyte string to wide character string(マルチバイト文字列からワイド文字列への変換)」を意味し、再開可能な変換状態を維持しながら、NULL終端されたマルチバイト文字列をワイド文字列表現へと変換します。この

  2. C/C++のsystem()関数とは?使い方と実行例を徹底解説

    この記事では、C/C++におけるsystem()関数の基本的な使い方と動作について、具体例を交えながら詳しく解説します。 system()関数は、C/C++標準ライブラリに含まれる関数の一つです。オペレーティングシステムのコマンドプロセッサ(コマンドプロンプト)やターミナルで実行可能なコマンドをプログラムから渡して実行でき、コマンドの処理が完了すると制御をプログラムに戻します。 この関数を使用するには、ヘッダーファイル<stdlib.h>(C++の場合は<cstdlib>)をインクルードする必要があります。 構文 system()関数の構文は以下の通りです。 int