私は中級レベルのCプログラマーです。私はCで簡単なコードスニペットを歩いていました
int a ; // A
const int b; // B
static int c; //C
void func(int d) // D
{
//.....
}
変数a、b、c、およびdのリンクは何ですか。a
デフォルトで外部リンケージ、、、b
およびc
内部リンケージがあると確信していますd
。私の理解は正しいですか?
これがこのサイトでの私の最初の質問です。
C99のセクションから6.2.2, Linkages of identifiers
、決定的な情報源は次のとおりです。
1 /異なるスコープまたは同じスコープで複数回宣言された識別子は、リンケージと呼ばれるプロセスによって同じオブジェクトまたは関数を参照するように作成できます。リンケージには、外部、内部、なしの3種類があります。
2 /プログラム全体を構成する変換ユニットとライブラリのセットでは、外部リンケージを持つ特定の識別子の各宣言は、同じオブジェクトまたは関数を示します。1つの変換ユニット内で、内部リンケージを持つ識別子の各宣言は、同じオブジェクトまたは関数を示します。リンケージのない識別子の各宣言は、一意のエンティティを示します。
3 /オブジェクトまたは関数のファイルスコープ識別子の宣言にストレージクラス指定子staticが含まれている場合、識別子には内部リンクがあります。
4 /ストレージクラス指定子externで宣言された識別子の場合、その識別子の前の宣言が表示されるスコープで、前の宣言が内部または外部のリンクを指定している場合、後の宣言での識別子のリンクは次のようになります。事前の宣言で指定されたリンケージ。以前の宣言が表示されていない場合、または以前の宣言でリンクが指定されていない場合、識別子には外部リンクがあります。
5 /関数の識別子の宣言にストレージクラス指定子がない場合、そのリンケージは、ストレージクラス指定子externで宣言されたかのように正確に決定されます。オブジェクトの識別子の宣言にファイルスコープがあり、ストレージクラス指定子がない場合、そのリンケージは外部にあります。
6/次の識別子にはリンクがありません。オブジェクトまたは関数以外のものであると宣言された識別子。関数パラメーターとして宣言された識別子。ストレージクラス指定子externなしで宣言されたオブジェクトのブロックスコープ識別子。
7 /翻訳ユニット内で、内部リンケージと外部リンケージの両方で同じ識別子が表示される場合、動作は定義されていません。
次に、変数に1つずつ取り組みます。
a
これは「ファイルスコープを持ち、ストレージクラス指定子を持たないオブジェクトの識別子」であるため、パート5で説明されています。したがって、外部リンケージがあります。b
パート5(ファイルスコープ、ストレージクラス指定子なし)でもカバーされています。したがって、外部リンケージ。c
static
ストレージクラス指定子があるため、パート3で説明します。内部リンクがあります。d
、関数パラメータであるパート6でカバーされています-リンケージはありません。Cではa
、b
外部リンケージがあり、c
内部リンケージがあります。C ++では、あなたは正しいでしょう、それb
はまた内部リンケージを持っているでしょう。
ケース「D」の場合、関数とパラメーターのどちらについて話しているのかわかりません。func
外部リンケージがあります。d
リンケージはありません。
b
私は、デフォルトで外部リンケージ、、、c
および内部リンケージを持っていると確信していますd
。私の理解は正しいですか?
いいえ!d
正式なパラメータであるため、リンクはありません。
C99から
次の識別子にはリンクがありません。オブジェクトまたは関数以外のものであると宣言された識別子。関数パラメーターとして宣言された識別子。ストレージクラス指定子externなしで宣言されたオブジェクトのブロックスコープ識別子。
さらにb
、C99には外部リンケージがあります。C ++では、ファイルスコープのconst修飾変数には内部リンクがあります。
a、b、cは、グローバルスコープで宣言されている場合、すべて同じリンケージを持っています。
dは関数パラメーターであり、その関数が呼び出されたときに作成され、関数が戻ったときに存在しなくなります