CとC++の場合も、2つのファイルでの同じ関数とグローバル変数の異なる宣言に関して2つの質問があります。
さまざまな関数宣言
次のコードフラグメントを検討してください。
file_1.c
void foo(int a); int main(void) { foo('A'); }
file_2.c
#include <stdio.h> void foo(char a) { printf("%c", a); //prints 'A' (gcc) }
ご覧のとおり、プロトタイプは file_2.cにある定義とは異なりますが、関数は期待値を出力します。
foo(int)
C ++の場合、リンク時の参照が未定義であるため、上記のプログラムは無効です。これはおそらく、他の関数シグネチャの存在が原因です。Cと比較すると、関数名には関数の引数のタイプを示す余分な文字が含まれていません。しかし、Cになると、それでは何ですか?同じ名前のプロトタイプは、引数の数とそのタイプに関係なく同じシグネチャを持っているため、リンカはエラーを発行しません。しかし、ここではどの型変換が実行されますか?次のようになりますか?
'A'
->int
->戻るchar
?または、この動作は未定義/実装定義ですか?グローバル変数のさまざまな宣言
同じグローバル変数の2つのファイルと2つの異なる宣言があります。
file_1.c
#include <stdio.h> extern int a; int main(void) { printf("%d", a); //prints 65 (g++ and gcc) }
file_2.c
char a = 'A';
CとC++の両方で、出力は65です。
両方の基準がそのような状況について何を言っているのか知りたいのですが。
C11標準では、次のフラグメントが見つかりました。
J.5.11複数の外部定義 (付録J.5共通の拡張機能)
キーワードexternの明示的な使用の有無にかかわらず、オブジェクトの識別子には複数の外部定義が存在する場合があります。定義が一致しない場合、または複数が初期化されている場合、動作は未定義です(6.9.2)。これは2つ以上の定義の存在を示していることに注意してください。私のコードには、1つしかないため、この記事がこの場合の参考になるかどうかはわかりません...