2010年3月18日 星期四

Scope regions in C and C++

Many programmers have difficulty distinguishing the concepts of scope, storage allocation, and linkage. Dan begins the process of sorting them out.

Like many other programming languages, C employs concepts such as scope and storage allocation. The C standard also employs the lesser known concept of linkage. Some other programming languages employ this concept as well, but few aside from C++ use the same terminology as C.
----------------------------------------
就像是其它的程式語言,C語言也有scope 及 storage allocation 這二個觀念 .
而C語言中也有linkage這個.其它的語言也有類似這些的觀念,但是C++對於C的名稱最為接近
----------------------------------------
Although most programmers understand scope and storage allocation well enough to cope with common programming situations, their understanding often breaks down when confronted with anything out of the ordinary. They also seem to have a sense of what linkage is, but don't really understand how it's distinct from the other concepts.
-----------------------------------------
雖然大多的程式設計師 ,都可以以scope 及 storage allocation來面對大多數的程序狀況.
但他們時常停下來面對面對其它的狀況.他們也大概上了解何謂linkage,但是不是真正能
區分其它的觀念的不同.
----------------------------------------

Much of the confusion stems from the complex semantics of storage class specifiers such as extern and static. The keyword static is particularly inscrutable. Sometimes it affects the way a program allocates storage. It can also affect how the linker resolves names as it links object files together. In C++, it can even restrict the behavior of class member functions. Understanding these distinctions can help you implement your designs more effectively and avoid some maintenance headaches.
------------------------
大多會感到困惑的是,較複雜的semantics of storage class specifier(extern,static)
尤其是 static令人困惑.因為static它可能有時會影到allocate storage也有時會影到
linker.而在C++中,它也會路class member functios.有關.了解它(static) 有助你解決問題及設計
------------------------
In this installment, I'll explain how the C standard defines the concept of scope. The C++ standard describes scope much as the C standard does, but with a few noteworthy differences. I'll focus initially on what the C standard says and point out the differences with C++ as appropriate. I'll try to be reasonably precise without swamping you with unnecessary details.
-----------------------
在這裡,我將會解釋C是如何定義其scope的觀念的.而對C++也大概上相同.
我將主要放在C上,並指出和C++不同處.
-----------------------
Translation units
As you well know, a C program can consist of numerous source files. A compiler processes one source file at a time. A source file usually contains #include directives that refer to headers. The compiler's preprocessor merges those headers with the source file to produce a transitory source file, which the standard calls a translation unit. Translation units are also known as compilation units.
----------------------
Translation unit
就你所知的,C語言可由數個source file所組成的.而 compiler 也只能一次處理一個檔案.而在source file中通常包含有參照header的指令 #include . 而compiler's preprocessor會將這些source file及header file合併成一個 暫時性的file(translation unit).其即為comilation unit.
----------------------
Later phases of the compilation process transform each translation unit into an object file or object module. The linker combines object files and library components to produce an executable program.
As you'll see, you can't talk knowledgeably about scope and linkage without mentioning translation units.
---------------------------
經過compilation process轉換這這translation unit至object file or object module.而再經過linker將object file及library合起來成為個executable program
---------------------------
Declarations and definitions
A declaration is a construct in the source code that introduces one or more names into a translation unit and associates attributes with those names. Alternatively, a declaration might simply redeclare a name introduced by a declaration that appeared earlier in the translation unit.
-----------------------
宣告'及 定義
    而宣告就是用來將一或多個name引入到translation unit 並且將跟name相關的聯結起來.
要不然,就是用來重新宣告(declaration)早先已經存在translation unit的name.
-----------------------
A declaration might also be a definition. Informally, a definition is 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."
----------------------
而declaration也可能是一個definition.詳細地說,就是definition不止是declaration name,而且提供了compiler所需的資訊
----------------------
For functions and objects, a definition is a declaration that generates storage. It's easy to tell when a function declaration is also a definition--a function definition has a body, which generates storage in the code space. For objects, the distinction is not so simple--it depends on the object's scope, linkage, and initializer. We'll get there in due time.
-----------------------
對於function及object這二個, 一個定義(definition)也是一個宣告(declaration)而且也能產生其storage.對於functiion來講若其function在declaration時帶有一個body時,它就可以在code space中產生storage.而對於object來講則,並不是那麼容易,它需要其object's scope,linkage,及initialzer來判斷是否會產其storage.
-----------------------
In C, a struct declaration never generates storage, so C doesn't distinguish struct definitions from other struct declarations. C++ does. In C++, a struct declaration is also a definition if it has a body, as in:
----------------
在C語中,其對於struct的宣告(declaration)是不會產生storage,是故C語言中對struct
definition不會對區別它是否來自其它的struct decalaration.而在在C++也是,對C++中,
若其struct declaration有包含一個body,則其則為一個definition了.
(C++/C 相同,是以是否在declaration中是否有包含有body來決定其是否也為definition),像是
----------------
struct widget   // a definition
    {
    ...
    };
It's just a declaration if it lacks a body, as in:
//若沒有包含其body時,如下
struct widget;  // just a declaration

The C standard uses more complicated verbiage to distinguish these different forms of struct declarations. I prefer C++'s approach.

In both C and C++, all typedef and enumeration constant declarations are also definitions.
------------------------
在C語言中,使用了更雜複的關係來區分不同的struct declaration.
故在此我喜歡用C++.

不論是C/C++中,所有使用typedef 及 enumeration constatn來宣告(declaration)的,都也是definition
------------------------
Scope regions in C
When the compiler encounters the declaration of a name, it stores that name and its attributes in a symbol table. When the compiler encounters a reference to a name, it looks up the name in the symbol table to find those attributes. Each declared name is visible--can be found by lookup--only within a portion of the translation unit called its scope.
----------------------
當compiler遇到一個宣告名稱(declaration of a name)時 ,它會將其名稱及相關的參數 存在一個
"system table"中.當compiler遇到需參照的名稱時(a reference to a name),它會在其system table中找尋與name相關的參數.對於其名稱是否可以在translation unit可以被找到的範圍,即稱為
"scope"
----------------------
Some programming languages use dynamic scoping, in which name lookup is done at run time and may yield different results depending on the state of the running program. That is not the case with C and C++. Both languages use static scoping and do all name lookup at compile time.
-------------------
有些程式是使用dynamic scoping的,這時其結果需要從其執行時及程式會產生不同的結果.
而在C/C++中是屬於static scope的,並在compiler time時處理其scope的問題的.
-------------------
C has four kinds of scope: (C有下列四種的scope)
• A name has file scope if it's declared in the outermost scope of a translation unit, that is, outside of any function, structure, or union declaration. Its scope begins right after its declaration and runs to the end of the translation unit.
//file scope ,它是最外層的translation unit,像是外層的function,struct或是union 的定義.
//它的範圍是從它的宣告開始的,而在其translation unit最後結束
• A name (other than a statement label) has block scope if it's declared within a function definition (including that function's parameter list) or in a brace-enclosed block within that function. Its scope begins right after its declaration and runs to the end of the block immediately enclosing that declaration.
//block scope: 它是指宣告在function's definition(包含其function's parameter list) 中或是和--functio所brace-enclosed block中.
//它的範圍是 從它的declaration開始並且在其block enclosing的結尾結束
• A name has function prototype scope if it's declared in the function parameter list of a function declaration that is not also a definition. Its scope begins right after its declaration and runs to the end of the parameter list.
//function prototype scope :它是指的是宣告在一個function declaration且parameter list中
//它的範圍,為在它宣告後,並在其parameter list後,結束
• Statement labels, and only statement labels, have function scope. A label can be defined only in the body of a function definition and is in scope everywhere in that body, even before the label has been defined.

//function scope :它只能適用於 statement label中,且只能被定義在the body of function中.
//範圍 為 :任何在其body中,而且即使其lable已經被定義過了.

For example, in Listing 1:
• Object k and functions f and g have file scope.
• Parameter i in function f and parameter n in function h have function prototype scope.
• Parameter i, objects j and k, and function h, all within function g, have block scope.
• Label done in function g has function scope.



















Most programmers, not just C and C++ programmers, refer to names declared in an inner scope (a block scope) as local names, and to names declared at the outermost scope (file scope) as global names. The C++ standard uses the terms local and global in this sense, but the C standard rarely does.
-------------------------------------------------------
對大多數的程式員來說,不論是C/C++.對於宣告在 an inner scope 都是稱為local name,
而宣告在t最外層的scope(file scope)則稱為global name.
-------------------------------------------------------
The exact point that a name's scope begins depends on the way that name is declared.
The scope of such a name begins just after the end of its declarator and before its initializer, if present. A declarator is the part of an object or function declaration consisting of a name being declared, possibly surrounded by operators such as *, [], and (). For example:

long int *p = NULL, x[N];
has two declarators, *p and x[N]. In this example, p's scope begins at the = (equal sign), and x's scope begins at the semicolon.
----------------------------
對於其一個name的scope是從何時開始,是要從 其name是如何被declared.
一般來講,一個name的scope是從它宣告後開始的, 然後在它還沒被initializer時.
而來宣告name,是由declarator及.....所組成的.
declarator是組成object or function的宣告中的部份,它可能有些operator(*,[],())

在此例中,有二個declarators, *p及 x[N].而其 "p"的scope開始於 "=" ,而其 x的scope為其";"
----------------------------
The scope of a structure, union, or enumeration tag begins just after the appearance of the tag in the type specifier that first declares the tag. For example, the name s appearing in:

struct s
    {
    ...
    };
is a tag. The names of unions and enumerations are also tags. The scope of s in the above declaration begins at the opening brace immediately after s.
-----------------------
而對於 struct,union,or enumeration 的scope,則開始於tag
-----------------------




Similarly, the general form of an enumeration definition is:

enum tag { enumerator, enumerator, ...,     enumerator };
Each enumerator is an identifier that names a constant, optionally followed by an = and an expression that specifies the constant's value. The scope of an enumeration constant begins just after the appearance of its defining enumerator.
Consider:

enum color { red, green = 2, blue = 4 };
Here, red's scope begins at the first comma, green's begins at the second, and blue's begins at the closing brace.
------------------------
------------------------
According to the C standard, a name in an inner scope can hide a name from an outer scope. For example, in Listing 1, the object k local to function g hides the global object k. The local k hides the global one in the sense that, when the compiler looks up k in the scope of the local k, it finds only the local k, never the global one. Thus, the assignment in g modifies the local k, not the global one.
The C++ standard explains the behavior of nested scopes differently, but the effect is pretty much the same.
------------------------
根據C語中,在inner scope的name可以忽略(穩藏) 在outer scope的name.
像是例1中的 function a 中的local object k 會隱藏 global object k.因此若compiler在處理這段時
會只會找到local object k,而不會參照到gobal object k.
------------------------
Scope regions in C++
The scope regions of C++ are somewhat different from those in C. C++ identifies five kinds of scope: function, function prototype, local, namespace, and class. The first two--function scope and function prototype scope--are the same in C++ as they are in C. Local scope corresponds to C's block scope, namespace scope corresponds to C's file scope, and class scope is something new.
In C++, local scope extends the concept of block scope to account for some added features of C++, such as the ability to declare a variable in the initialization step of a for statement, as in:

for (int i = 0; i < N; ++i)
    ...
C++ provides a facility called namespaces for grouping names that would otherwise be crowded into file scope. C++ generalizes the rules for names declared at file scope to include names declared in namespaces as well. In C++, a name has namespace scope if it's declared either in a namespace of the form:

namespace identifier
    {
    ...
    }
or in what C calls file scope. Accordingly, the C++ standard shuns the term file scope in favor of global namespace scope, or just global scope.
C++ also introduces the concept of class scope for names declared within the brace-enclosed body of a class definition. (Classes in C++ include structures and unions, as well.) In C++, each class introduces a new scope, so the same name can be declared as a member in more than one class.
C doesn't quite have a corresponding notion of structure scope. Rather, the C standard says that each structure or union has a separate name space for its members. The C standard uses the term name space (two words) to mean something quite different from the namespace (one word) construct of C++. In C, a name space is a region of the compiler's symbol table. Despite the different verbiage in their respective standards, C and C++ look up structure and union members in much the same way.

Scope and linkage
The concept of scope is meaningful only within a single translation unit. Strictly speaking, a name declared in the global scope is simply a name declared at the outermost scope in a translation unit. That name isn't necessarily known in other translation units.
Despite what you may have learned, neither C nor C++ has any kind of scope that spans from one translation unit to another. Rather, a name declared in one translation unit can refer to a name defined in another translation though a property called external linkage. Stay tuned.


 http://www.embedded.com/columns/programmingpointers/202600398

沒有留言:

張貼留言