A name declared in C or C++ may have attributes such as type, scope, storage duration, and linkage. Not every name has all of these attributes. For example, a function name has a type, a scope, and a linkage, but no storage duration. A statement label name has only a scope.
An object's
type determines the object's size and memory address alignment, the values the object can have, and the operations that can be performed on that object. A function's type specifies the function's parameter list and return type.
A name's
scope is that portion of a translation unit in which the name is visible.
1 (A
translation unit is the source code produced by the preprocessor from a source file and all its included headers.) C supports four different kinds of scope: file scope, block scope, function prototype scope, and function scope. C++ generalizes file scope into namespace scope, and adds class scope.
An object's
storage duration determines the lifetime of the storage for that object.
2 That is, it determines how and when during program execution the storage for that object comes and goes. Each object in C and C++ has one of the following three storage durations: static, automatic, and dynamic. Only objects have storage duration. Enumeration constants, functions, labels, and types don't.
Which brings us to linkage. A name's
linkage affects whether two or more declarations for that name are valid, and if so, whether they refer to the same entity (such as a function or an object). Understanding linkage clears up a number of misconceptions about the behavior of C and C++ programs.
In my earlier article on the scope rules,
1 I explained the distinction between declarations and definitions, but omitted some details. Those details are pertinent to the concept of linkage, so let's take a look at them first.
DECLARATIONS AND DEFINITIONS
A
declaration associates attributes with names. A declaration either introduces a name into the current translation unit or redeclares a name introduced by a declaration that appeared earlier in the same translation unit. A declaration for a name might also be a
definition. Informally, a definition is a declaration that not only says "here's a name," but also "here's all the information the compiler needs to create the code for that name".
C++ lets you declare all sorts of things that aren't valid in C, such as classes, namespaces, and linkage specifications. Not surprisingly, these features make the distinction between definitions and other declarations, as well as the linkage rules, more complicated in C++ than in C. However, we don't really need to consider all those features to explain linkage--using just functions and objects should provide adequate illustration.
For function declarations that are valid in both C and C++, the rule for deciding when a function declaration is also a definition is the same for both languages, namely, that a function declaration is also a function definition if it includes a brace-enclosed body, as in:
int abs(int v)
{
return v < 0 ? -v : v;
};
A function heading without a body, as in:
int abs(int v);
is just a declaration.
For object declarations that are valid in both C and C++, the rule for deciding when an object declaration is also a definition is--surprisingly--simpler in C++ than in C. In C++, an object declaration is also a definition unless it contains an
extern specifier and no initializer.
For example, all of the following object declarations are also definitions in C++:
int i; // definition
static int j; // definition
extern int k = 0; // definition
They are definitions whether they appear at file scope, namespace scope, or block scope.
The following object declaration is not a definition:
extern int m; // non-defining declaration
//
1. 若 extern int m;
宣告在 file scope中時,若其以下的程序中並沒有使用此一變數
則在object file中並不會出現,即使不開最佳化設定 ;
反之.若以下程序中有使用到其變數 m ,但又不能在其 "有(宣告)declare extern int m的檔案中,找到其定義值時, 其object file中為
00000000 T abs
U foo
00000004 C i
00000000 b j
U m
(00000000 D m) //若有被定義時,
00000014 T main
U printf
2.在全域變數時,若定義其值為"0"
其object file 的符號 為 B(BSS,未初化資料),而非D(已初始化資料,RW)
//