2016-06-14 6 views
-2

主な質問です:Cコンパイラは、異なるソースコード内の関数の主のために複数の定義を処理しない方法は? ように:Cコンパイラはどのように異なるメイン関数定義を扱いますか?

無効メイン(無効)

int型メイン(無効)

int型のmain(int型のargc、charは* ARGV []) ...

私にはわかりませんこれは、ためにCコードがEXTERN「C」を使用せずにC++コードにリンクされているだけでなく、私は、Linuxのプログラマのマニュアル(シェル上の単なるmanコマンド)を介して照会された場合にのみ発生することが、名前の符号化とは何かを持っている場合関数open(man 2 open)とそれに対して2つの署名が表示されます:

OPEN(2)Linuxのプログラマーズ・マニュアル

NAME

open, creat - open and possibly create a file or device 

SYNOPSIS

#include <sys/types.h> 
    #include <sys/stat.h> 
    #include <fcntl.h> 

    int open(const char *pathname, int flags); 
    int open(const char *pathname, int flags, mode_t mode); 

    int creat(const char *pathname, mode_t mode); 

どのようにこの仕事はできますか?メイン関数の定義と同様に扱われますか?文字通り

+1

メインの複数の宣言が異なる型か複数の定義であることを意味するのだろうかと思います。あなたの行動がはっきりしていないサンプルコード(あなた自身のプログラム)を与えれば助けになります。また、[linux]と[C++]との関係も不明です。 – PJTraill

+1

リンカの制限に対応するために、名前のマングリングはCの名前に起こるのではなく、オーバーロードされたC++の名前に起こります。そのため、Cコンパイラ(そしておそらくリンカ)があなたのプログラムで行うことには関係しません。 – PJTraill

+0

これは有効なCコードではありません。 CとC++は**異なる**言語です!同一の構文/文法であっても、異なるセマンティクスを持つことができます。 – Olaf

答えて

2

とにかくそれが好きです。あなたが標準で禁止さ2つの方法のいずれかでmainを宣言していない、またはあなたがの両方マナーそれを宣言した場合、それは望んでいた場合、コンパイラは月にあなたの車をテレポートできます。それ以上の合理化は無意味です。

[C99: 5.1.2.2.1/1]:[..]それはintの戻り型とし、パラメータなしで定義されなければならない:[..]二つのパラメータ又は [..]

[C99: 5.1.2.2.1/2]:宣言されている場合、main関数へのパラメータは次の制約に従わなければならない:[..]

[C99: 3.4.3/1]:未定義の動作は
挙動は、移植性や誤ったプログラム構築物のまたは誤ったデータの使用に、そのためにこの規格は

4

openが実際に過負荷または複数の宣言を持っていない何の要件を課していません。それはopen(const char *pathname, int flags, ...)として宣言だと3番目の引数はva_argで読み取るとflagsO_CREATを含む場合mode_tとして解釈されます。

mainという複数の定義がある場合、または同じ名前の複数のシンボルがある場合は、おそらくリンカーエラーが発生します。 Cプログラミング言語の

+0

ありがとうzneak、偉大な答え – joaopauloribeiro

+0

私は誤解していると思う、主な質問は、同じソースコード内に2つ以上の定義を持つことではないが、コンパイラはどのように異なるコードで異なる定義を扱うか? main(void)またはint main(void)... – joaopauloribeiro

+1

@joaopauloribeiroコンパイラは、 'main'がCランタイムによって正しく呼び出されるようにする責任があります。呼び出される方法は、引数があってもなくてもかまわないし、値が返されても返されないかを考慮しなければなりません( 'main'がC標準への拡張として' void'を返すことが許されるプラットフォームで)。特殊なケースとして扱うことができます。あなたは必ずしもそのような寛大さを他の機能で得ることはありません。 – zneak

3

典型的な実装では、関数にあまりにも多くの引数を渡す、発信者に対して寛容です。スタートアップコードがmainに呼び出したときにmainは3番目の引数が環境にある

int main(int argc, char *argv[], char *environ[]); 

として宣言されたかのようにUNIXライクなシステムでは、それは3つの引数を渡します。 mainがそれより少ないパラメータで定義されていた場合、一般的な呼び出し規約と同じようにすべてが正常に機能し、余分な引数は傷つかないように配置されます(例えば、最初の引数の上のスタックや余分なレジスタ) 。

これまではopen関数も同様に機能していました。openはプロトタイプなしで宣言されたため、渡された引数の数をコンパイラが確認できませんでした。 openの定義は、openが呼び出されたときに3番目の引数が問題にならなかった3番目の引数のスタックにあるものを取り込みます。openは、O_CREATなしで呼び出されます。

+0

オープン関数がスタック内にある「何でも」を取得すると、スタックを他の関数で破壊する可能性がありますか? – joaopauloribeiro

+1

人生のすべてと同じように、あなたのシェアを下回ることはできますが、それ以上の努力をしてその結果を苦しめてください。 – SergeyA

+1

@joaopauloribeiroそれは決して引数を上書きしないので、 'open'は決して一番上のスタックフレームではないので、これは問題ではありません。 – fuz

関連する問題