[解決済み] なぜCの関数は名前解決ができないのか?
質問
最近面接を受けたのですが、そのときに聞かれた質問のひとつが
extern "C"
をC++のコードで使うことです。私は、Cは名前解決を使わないので、C++のコードでCの関数を使うためですと答えました。なぜCはname-manglingを使わないのかと聞かれましたが、正直言って答えられませんでした。
C++コンパイラが関数をコンパイルするとき、関数に特別な名前を付けるのは、主に、C++では同じ名前のオーバーロードされた関数があり、コンパイル時に解決しなければならないからだと理解しています。C では、関数の名前は同じままか、おそらくその前に _ が付きます。
私の疑問は、C++ コンパイラーが C の関数をも混乱させることを許可することの何が問題なのか、ということです。私は、コンパイラーがどのような名前を付けるかは問題ではないと考えていました。私たちは C と C++ で同じように関数を呼びます。
どのように解決するのですか?
上記で回答があったようなものですが、文脈を整理してみます。
まず、Cが最初に来ました。そのため、C が行うことは、ある意味、デフォルトのようなものです。なぜなら、C は名前を混乱させないからです。関数名は関数名です。グローバルはグローバル、といった具合です。
その後、C++が登場しました。C++はCと同じリンカーを使い、Cで書かれたコードとリンクできるようにしたかったのですが、C++はCのquot;mangling"(またはその欠如)をそのままにしておくことができませんでした。次の例を見てください。
int function(int a);
int function();
C++では、これらは異なる本体を持つ、異なる関数です。もしどれもマングルされていなければ、両方とも "function" (または "_function") と呼ばれ、リンカーはシンボルの再定義について不満を漏らすでしょう。C++の解決策は、引数の型を関数名の中に紛れ込ませることでした。つまり、1つは
_function_int
で、もうひとつは
_function_void
(というように変更すると、衝突が回避されます。
さて、問題が残りました。もし
int function(int a)
が C モジュールで定義されていて、C++ コードでそのヘッダ (つまり宣言) を取ってきて使っているだけなら、コンパイラはリンカにインポートするように命令を生成します。
_function_int
. この関数が定義されたとき、Cモジュールではそのように呼ばれなかった。それは
_function
. これはリンカエラーの原因となります。
このエラーを回避するために 宣言 で、コンパイラにそれが C コンパイラとリンクされたり、コンパイルされたりするように設計された関数であることを伝えます。
extern "C" int function(int a);
C++コンパイラは、インポートするために
_function
よりも
_function_int
に変更すれば、すべてうまくいきます。
関連
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] C++で仮想関数が必要な理由とは?
-
[解決済み] switch文の中で変数を宣言してはいけないのはなぜですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)
-
[解決済み】Enterキーを押して続行する
-
[解決済み】変数やフィールドがvoid宣言されている
-
[解決済み] C++でextern "C "を使用した場合の効果は?