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

C言語ではコンパイルできるのにC++ではエラーになるプログラム7選

C++は、C言語にオブジェクト指向などの機能を追加する形で設計された言語です。そのため、C言語で書かれたプログラムの多くはC++コンパイラでもそのままコンパイルできます。しかし、言語仕様の違いにより、Cでは問題なくコンパイルできるのに、C++ではコンパイルエラーになるプログラムも存在します。

以下に、Cコンパイラでは通るものの、C++コンパイラではエラーとなる代表的なコード例を7つ紹介します。

1. 関数を宣言前に呼び出しているケース

このプログラムでは、myFunction() を宣言よりも先に呼び出しています。従来のC言語では暗黙的な関数宣言が許されるためコンパイルできますが、C++では事前の宣言が必須のためエラーになります。

サンプルコード

#include<stdio.h>
int main() {
    myFunction(); // 宣言前に myFunction() を呼び出している
}
int myFunction() {
    printf("Hello World");
    return 0;
}

実行結果(C)

Hello World

コンパイル結果(C++)

[Error] 'myFunction' was not declared in this scope

2. 通常のポインタでconst変数を参照するケース

C++では、通常のポインタ(int*)で const 変数を指すことはできません。一方、C言語ではこのような代入でもコンパイルが通ってしまいます。

サンプルコード

#include<stdio.h>
int main() {
    const int x = 10;
    int *ptr;
    ptr = &x;
    printf("The value of x: %d", *ptr);
}

実行結果(C)

The value of x: 10

コンパイル結果(C++)

[Error] invalid conversion from 'const int*' to 'int*' [-fpermissive]

3. voidポインタを別のポインタ型に代入するケース

void* 型のポインタを int* や char* など別のポインタ型に代入する場合、C++では明示的な型キャストが必要です。C言語ではキャストを省略してもコンパイルできます。

サンプルコード

#include<stdio.h>
int main() {
    void *x;
    int *ptr = x;
    printf("Done");
}

実行結果(C)

Done

コンパイル結果(C++)

[Error] invalid conversion from 'void*' to 'int*' [-fpermissive]

4. const変数を初期化せずに使うケース

C++では const 変数は必ず初期化しなければなりませんが、C言語では初期化しなくてもコンパイルが通ります(ただし値は不定になります)。

サンプルコード

#include<stdio.h>
int main() {
    const int x;
    printf("x: %d",x);
}

実行結果(C)

x: 0

コンパイル結果(C++)

[Error] uninitialized const 'x' [-fpermissive]

5. 「new」を変数名として使うケース

C言語では「new」という名前の変数を定義できますが、C++では new はメモリを動的に確保するためのキーワードであるため、変数名として使用することはできません。

サンプルコード

#include<stdio.h>
int main() {
    int new = 10;
    printf("new: %d",new);
}

実行結果(C)

new: 10

コンパイル結果(C++)

[Error] expected unqualified-id before 'new'
[Error] expected type-specifier before ')' token

6. int値をchar*型ポインタに代入するケース

整数値をそのまま char* 型ポインタに代入するコードは、C++では int から char* への不正な変換としてエラーになりますが、C言語では問題なくコンパイル・実行できます。

サンプルコード

#include<stdio.h>
int main() {
    char *c = 123;
    printf("c = %u", c);
}

実行結果(C)

c = 123

コンパイル結果(C++)

[Error] invalid conversion from 'int' to 'char*' [-fpermissive]

7. main() の戻り値型をvoidにするケース

C言語では main() の戻り値型として void を使えますが、C++では戻り値型は必ず int でなければなりません。

サンプルコード

#include<stdio.h>
void main() {
    printf("Hello World");
}

実行結果(C)

Hello World

コンパイル結果(C++)

[Error] '::main' must return 'int'

まとめ

このように、C++はC言語と高い互換性を持つ一方で、型チェックの厳格化や新しいキーワードの追加など、より厳密な言語仕様を採用しています。C言語のコードをC++環境でビルドする場合は、こうした違いを理解しておくことが重要です。移植性を高めるためには、関数の事前宣言、明示的なキャスト、const 変数の確実な初期化、標準に準拠した int main() の定義などを心がけるとよいでしょう。

  1. Windows 10でアンインストールできないプログラムを削除する7つの対処法

    プログラムを削除しようとしても、Windows 10のPCからアンインストールできずに困ったことはありませんか?この問題はさまざまな原因で発生し、プログラム自体ではなくシステム側に原因があるケースもあります。幸い、ほとんどのアンインストールの問題は、簡単な手順で解決できます。正しい方法を試せば、いつもどおりプログラムを削除できるようになりますよ。1. 設定アプリを使ってアンインストールするWindows 10にインストール済みのアプリを削除する最も簡単な方法は、標準搭載の「設定」アプリを使うことです。コントロールパネルなど別の方法で削除に失敗した場合は、「設定」アプリを試してみてください。うま

  2. C++プログラムにおける二分探索(バイナリサーチ)の基本と実装

    二分探索(バイナリサーチ)とは二分探索は「半区間探索」「対数探索」「バイナリチョップ」とも呼ばれる検索アルゴリズムで、ソート済みの配列の中から目的の値が存在する位置を効率的に見つけ出します。基本的な仕組みは非常にシンプルです。まず、探したい値(ターゲット値)を配列の中央の要素と比較します。一致しなかった場合は、ターゲット値が存在し得ない半分を丸ごと排除し、残りの半分に対して同様の比較を繰り返します。この「中央との比較」と「範囲の絞り込み」を続け、ターゲット値が見つかるか、検索範囲が空になる(=配列にその値が存在しない)かのどちらかで処理が終了します。アイデア自体は簡単ですが、正しく実装するには