C言語関係掲示板

過去ログ

No.458.スコープとリンケージ

[戻る] [ホームページ]
No.3297

変数宣言
投稿者---初心者(2002/11/02 23:11:07)


はじめまして、初心者です。

--------------- Source 1 ---------------------
#include <stdio.h>
int i = 3;

void main (void) {
printf ("%d\n", i);
}
----------------------------------------------

--------------- Source 2 ---------------------
#include <stdio.h>
static int i = 3;

void main (void) {
printf ("%d\n", i);
}
----------------------------------------------

この二つの変数宣言に違いは、あるのでしょうか?

No.3306

Re:変数宣言
投稿者---TDa(2002/11/03 02:12:12)



>この二つの変数宣言に違いは、あるのでしょうか?

スコープの違いです。
1はコードのどこからでも参照できますが2はファイルの外からはアクセスできません。

ブロック中のstaticとは意味が違いますのでご注意を。

No.3307

変数宣言
投稿者---初心者(2002/11/03 14:12:04)


>ブロック中のstaticとは意味が違いますのでご注意を。

回答、ありがとうございます。

No.3342

Re:変数宣言
投稿者---かずま(2002/11/05 23:10:48)


> スコープの違いです。
> 1はコードのどこからでも参照できますが
> 2はファイルの外からはアクセスできません。

この説明を間違いだとは言いませんが、規格書に厳密に従うと、ちょっと
問題があります。

Source 1 の int i; のスコープは、この宣言から、ファイルの最後まで。

Source 2 の static int i; のスコープは、この宣言から、ファイルの最後まで。

だから、スコープは同じです。

次のプログラムを見てください。
  1: void f1()
  2: {
  3:     a = 1;
  4: }
  5: 
  6: int a;             /* 1 */
  7:                    /* 1 */
  8: void f2()          /* 1 */
  9: {                  /* 1 */
 10:     a = 2;         /* 1 */
 11:     {              /* 1 */
 12:         int b = a; /* 1 */
 13:         int a;     /* 2 */
 14:         a = 3;     /* 2 */
 15:     }              /* 2 */
 16:     a = 4;         /* 1 */
 17: }                  /* 1 */

6行目の a は、どこからでも参照できるわけではありません。
3行目からは参照できません。
6行目の a のスコープが /* 1 */ の行だからです。
13行目の a のスコープは /* 2 */ の行です。

6行目を static int a; に変えても同じです。

では、static のあるなしで何が違うのかというと、リンケージです。

他のファイルで、extern int a; があると、そのファイル内で、その行から
ファイルの最後またはブロックの最後までが、その a のスコープになります。

そして、そのファイルの extern int a; の a と、こっちのファイルの
int a; の a とは、外部結合(external linkage) なので、リンクされて
同じオブジェクトとなります。

こっちのファイルで、static int a; と宣言すると、それは内部結合なので
他のファイルの a とリンクすることができなくなります。

このように、規格書では、スコープとリンケージを、はっきり区別しています。

しかし、リンケージという用語には一切触れず、アクセスできるかできない
かということで、リンケージもスコープの一種であるかのように説明している
本が多数存在するのも事実です。