2010年3月18日 星期四

Storage class specifiers and storage duration

Storage class specifiers don't specify scope but combine with scope to determine storage duration. Here's the second part in a series on scope, storage allocation, and linkage.
----------------------
Storage class specifier 並不是決定 scope,但是和scope合起來時,可以決定storage duration. 這裡是 "scope,storage allocation and linkage"的第二部份

A declaration is a source code construct that 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 might also be a definition, which provides not just some of the attributes of a name, but rather all the information the compiler needs to create the code for that name.
-------------------------
 "A declaration"是組成source code的成分,它會和一個 names's attributes聯結.一個declaration也表示著,它把這個name引入到目前的translation unit中,或者是重新引入"在同一個tranlation unit"中已存在的一個name,(卻重新宣告). 一個declaration也可能是一個definition,若是definition時,它不止是對提供tranlation unit一個屬性為name物件.更提供了所有的相關的資訊,使得compiler可以對其動作(產生相對應的code;declaration則只能提供說有這個東西存在,)
-------------------------

Among the attributes that a name may have are its 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.
------------------------------------
對一個name可以提供屬性有 type,scope,storage duration and linkage.
並不是所有name都具有這些屬性
(像是: function name :只可以有 type,a scope,linkage.沒有storage duration.
           statement label name :則只有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. I've discussed the concept of data types in prior columns.1, 2
 ---------------------------------------
一個object's type決定了其物件的size 及 memory address alignment.及其物件對於value的範圍及其物件可以操作的功能. A function's type則特別地指出其function 's parameter list及return type.
----------------------------------------
I devoted my November column to the concept of scope as it applies to C and C++.3 In essence, the scope of a name is that portion of a translation unit in which the name is visible. C and C++ each support several different kinds of scope, summarized in the sidebar entitled "Scope regions in C and C++."
--------------------------------------
 "the scope of a name"是屬於translation unit的部份,在裡面是說明了一個name是否可見度,(可被參照).C/C++中,都支援了多樣的scope,而總結在"Scope regions in C and C++"
--------------------------------------
  Scope regions in C and C++
C and C++ each support five different kinds of scope regions. Although the C and C++ standards use different names for some regions and different verbiage to define those regions, the two languages support essentially the same five regions: 

------------------------------
C/C++ 各自支援了五種不同的scope regions,雖然C/C++分別使了不同的名稱及不同的verbiage 來決定義這些regions.而這二種支擾了下列的五種regions:
------------------------------

  • In C, a name has file scope if it's declared in the outermost scope of a translation unit. C++ extends the concept of file scope to the broader concept of namespace scope. In C++, a name has namespace scope if it's declared either in a namespace definition or in what C calls file scope. The C++ standard refers to the C concept of file scope as global namespace scope, or just global scope.
  • 在C中,其中一個為"file scope" ,它是被declaraed在最外層的translation unit中.;在C++中則是擴大其觀念,稱為 namespace scope. 在C++中.一個宣告(declared)在namespace definition中,或者是在像C中的file scope中 ,這時則稱為namespace scope.在C++中對於C中的file scope改稱為 global scope
  • A name (other than a statement label) has block scope if it's declared within a function definition or a block nested therein.
  • 它是declared在一個function definition中,或是在一個block nested 內 :A name(即,不是statement label 外) 都有一個block scope.
  • 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.
  •  若它是declared在一個function declaration中的function parameter list中時,它並不是一個"definition"而是一個名為function prototype scope的宣告
  • Each statement label has function scope, which spans the body of the function containing the label.
  • 而其"statement label" 則是屬於function scope.即在其function 中是可以參照到其label的.
  • A name in C++ has class scope if it's declared within the brace-enclosed body of a class definition. Classes in C++ include structures and unions, so a member of a C++ structure or union has class scope as well. The C standard doesn't have a corresponding notion of structure scope, but rather says that each structure or union has a separate name space for its members. Despite the different verbiage in their respective standards, C and C++ look up structure and union members in much the same way.
  • 在C++中有個 "Class scope" ,它是說,若你宣告在一個Class definition 且被brace-enclosed body.裡的.在C++中對於Classes可以包括有 "structures "及 "unions" 所以對於 C++ 中的structure 或 union中的成員,都是屬於class scope.而在C語言中,則沒有相對於structure scope的符號.而是說對於每一一個structure 或是union中的成員(nembers)有一個獨自的name space.

Scope is closely related to, but nonetheless distinct from, the concepts of storage duration and linkage. The storage duration for an object determines how and when the storage for that object comes and goes. Linkage determines whether declarations in different scopes can refer to the same object or function. It's easy to confuse these concepts because they're so intertwined.
----------------------------------------
Scope是相互關聯的,但又不同於storage duration及linkage.像是對於 storage duration是在說一個object 決定 對於一個object的存儲空間來'去()是 "如何處理"及"何時執行" ; linkage 則是決定不論其宣告在不同的scope,都可以被參照到同一個object或是funcion中.
"type ; scope,storage duration , linkage"
----------------------------------------

Much of the confusion stems from the complex semantics of storage class specifiers, keywords such as extern and static. For example, the precise meaning of static depends on the scope in which it appears. Sometimes, declaring an object static affects the object's storage duration. It can also affect the object's linkage. Understanding these distinctions can help you program more effectively.
---------------------------------------
會令大多人 困惑的是複雜的 storage class specifier(storage duration)像是 "exten"及"static"用法 . 像是 對於 static 的用法,應決定於它在那一個scope可見. 有時宣告一個static 物件影響的是它的storage duration,又可能它會影響對於此一物件的linkage.故你必須去了解它的用法.
----------------------------------------
This month, I'll explain the syntax of storage class specifiers and the concept of storage duration in C and C++. I'll also show you how they're related to the concept of scope.
-------------------------------------
接下來,是對於storage class specifiers及對storage duration的相關觀念. 及它們(storage class specifier,storage duration) 對於scope的相關聯.
--------------------------------------
Storage class specifiers are keywords you can use in declarations to control storage duration and linkage. First I'll show you how they fit into the syntax. Then I'll explain their impact on semantics.
Every declaration in C and C++ has two principal parts: a sequence of zero or more declaration specifiers, and a sequence of zero or more declarators, separated by commas.

----------------------------------
Storage class specifiers它是用來對於一個物件的宣告時,控制它的storage duratioin 及 linkage.
在C/C++中每個object declaration,都可以分為二個部分,
1.一連串 的 (零/多個 ) declaration specifier
2.一連串的  (零/多個) declarator,
以";"分開.
-------------------------------------









A declarator is the name being declared, possibly surrounded by operators such as *, [], (), and (in the case of C++) &. In the previous example, *x[N] is a declarator indicating that x is an "array of N pointers to ..." something, where that something is the type specified in the declaration specifiers.
-----------------------------------
"declarator" 就是被宣告的name,可能會包含其它的符號(operator)所組成,像是 *,[],(),&
在此例中的 *x[N]--is ad declarator indicating that x is an "array of  N pointers to ..."
-----------------------------------
A declarator may contain more than one identifier. The declarator *x[N] contains two identifiers, x and N. Only one of those identifiers is the one being declared and it's called the declarator-id. The other(s), if any, must have been declared previously. The declarator-id in *x[N] is x.
----------------------------
有時,一個declarator可能包含有多個"identifier" .像是 *x[N]中就包含有二個identifiers(x,N)
但是在這當中,只有一個是有效的 declarator-id.
像是 *x[N]中的declarator-id 就是 x.

----------------------------
(The term declarator-id comes from the C++ standard. The C standard makes do without it, but I find it to be a useful concept.)
Some of the declaration specifiers leading up to a declarator can be type specifiers such as int, unsigned, long, const, or a user-defined type name. They can also be storage class specifiers such as extern or static, or function specifiers such as inline.
--------------------------------
一個 Storage class specifiers,分為declaration specifier,declartor.
而在declaration specifier中,
1.可以有 type specifiers (像是int,unsigned ,long,const ,user-defined)
2.storage class specifier(像是extern or static,
3.function    specifier       (像是inline.
--------------------------------
The type specifiers contribute to the type of the declarator-id; the other specifiers provide non-type information that applies directly to the declarator-id. For example:

static unsigned long int *x[N];
declares x as an object of type "array of N pointers to unsigned long int". The keyword static specifies x's storage class.
-------------------------------
一個"type specifers" 是由 declarator-id的type所提供的,而其它specifier則是提供了非type的資
訊給其declarator-id.
像是 : static unsigned long int *x[N];
是在說x 是個 "array of N pointer to unsigned long int" ,而static 則是它的storage class.
-------------------------------
The C standard lists five storage class specifiers: auto, extern, register, static, and typedef; however, C considers typedef to be a storage class specifier for syntactic convenience only. C++ doesn't consider typedef as a storage class, so I won't either.
-------------------------------
在C中,有五種的storage class specifiers : auto ,extern ,register,static,and typedef.
但在C中對於typedef只是為了方便用.而在C++中並不會將把typedef視為 storage class .
-------------------------------
The C++ standard lists mutable as another storage class specifier, but this, too, is more for syntactic convenience than anything else. Unlike the other storage class specifiers, mutable has no impact on storage duration or linkage. I don't consider it a storage class specifier for the purpose of this discussion.
A declaration need not have any storage class specifier and can have no more than one.
----------------------------
在C++也有類似,為了方便而把 mutable,歸類為storage class specifier,但它不會對storage duration or linkage造成 影響.
----------------------------

Storage duration
The storage duration of an object determines the lifetime of the storage for that object. That is, it determines that part of program execution during which storage for the object must exist. Programmers often use the term storage allocation instead of storage duration, but both the C and C++ standards favor the latter. Only objects have storage duration. Enumeration constants, functions, labels, and types don't.
-----------------------------
"Storage duration"
"the storage duration of an object"決定了對一個物件的 storage的lifetime.它決定了程式執行時,對於部份object的storage必須存在.而寫程式的人,太多是以"storage allocation"取代"stoarge duration". 特別注意的是,只有Object有其storage duration.像是Enumeration constats,function,label,type等...都不沒有其storage druation.
-----------------------------
Each object in C and C++ has one of the following three storage durations: static, automatic, and dynamic. (The C standard lists the third kind of storage duration as "allocated" rather than "dynamic" but then never uses the term after that. I'll call it dynamic.)
--------------
不論是C/C++中的物件中,有三種的storage duration :
1.static
2.automatic
3.dynamic
--------------
An object declared at file scope (in C) or namespace scope (in C++), or declared with the storage class specifier extern or static, has static storage duration. The lifetime of the storage for that object is the entire time that the program is executing.
-------------------
若是一個object 宣告在 file scope(in C) 或是 namespace scope( in C++).或是使用 storage class specifier(extern or static)來宣告時,這些都是具有static storage duration.
而其因static storage duration所影響的lifetime的object是從程式被執行時開始
-------------------
An object declared at block scope, and without the storage class specifier extern or static, has automatic storage duration. The lifetime of the storage for that object begins upon entry into the block immediately enclosing the object's declaration and ends upon exit from the block. Entering an enclosed block or calling a function suspends, but doesn't end, the execution of a block.
---------------------
當一個object在block scope中被宣告,而且宣告時並沒有加上storage class specifier(extern or static) ---這時,此一object 的 storage duration是屬於automatic storage duration.而這objcet的lifetime是從進入其enclosing the object's declaration,並且在end upon exit from the block.
---------------------
When a program allocates storage for an object by calling an allocation function, such as malloc in C or an operator new in C++, that object has dynamic storage duration. The lifetime of the object's storage lasts until the program passes the address of that object to a corresponding deallocation function, such as free in C or an operator delete in C++.
=================
當使用allocation function來對一個物件,它會對其物件allocate storage,(malloc ,new )此時其物件是屬於 dynamic storage duration.而其物件的storage 是持續的,直到其相對應的deallocation function來對其做deallocation.

 =================

Table 1 shows how C and C++ determine the storage duration for an object based on the storage class specifier in the object's declaration and the scope in which the declaration appears. For example, the first row (below the column headings) says that an object declared with no storage class specifier at block scope has automatic storage duration, but if it appears at file scope in C or at namespace scope in C++, it has static storage duration. If it appears as a structure or class member, then it has the storage duration of the structure or class object of which it's a member.
----------------------------
在Table 1中,是說明了C/C++是如何決定了其storage duration.(對應了storage class specifier及其the scope in whic the declaration appear.)
---------------------------
None of the entries in Table 1 specify dynamic storage allocation. Unlike objects with static or automatic storage duration, a program can't declare any objects with dynamic storage duration. A program can create them by calling an allocation function; it just can't declare them.
----------------------------
在Table 1並沒有標示出對於 dynamic storage allocation的內容.不像是對於 static or automatic object 的 storage duration.因為在程式中,是不能在宣告指明了其object是屬於dynamic storage duration. 但是,程式是可以使用allocation function 建立一個dynamic storage durartion object.
而不是宣告一個具有dynamic storage object.
----------------------------
 The mechanics of storage allocation
The exact manner in which static storage is allocated and deallocated depends on the target platform. However, allocating storage for an object with static storage duration typically costs nothing at run time because the compiler, linker, and loader together determine the size and address of the object before the program starts running. From the running program's perspective, an object with static storage duration is always there.
----------------------------
對於static storage 正確方法 是 要依其target platform來 allocate and deallocate.
然而,對於一個static storage duration的object是並不需要在程式run時去分配存儲空間的(storage),因為在comipler,linker,and loader時就會在程式執行前已決定好其static object的size and address.故從程式來看(static object),它都是永遠存在的.
----------------------------
Typical C and C++ programs allocate automatic storage on a run-time stack, often the same stack that they use for storing function-call return addresses. Allocating storage for a local object isn't free, but it's usually dirt cheap--just one machine instruction. For example, in:
----------------------
一般在C/C++中其automatic storage object是建立在 run-time statck.而通常其stack也當做儲存function-call return address .在處理local object時是需要去空間中尋找,並建立的.不像是static 是在compiler時就決定好了.但是對於local object的處理是相當容易的.因為只需大楖一個指令即可
----------------------
int foo(int v)
    {
    int m;
    ...
    return m;
    }
function foo has a single local object, m. The compiler determines m's size from its type, typically 2 or 4 bytes. When it compiles foo, the compiler simply generates an instruction such as:

sub sp, 4
 
as one of the first instructions in the function body to carve room for an int on the stack. (This example assumes that an int object occupies 4 bytes and that the stack grows downward from higher addresses to lower addresses.)
 
-------------------
 這裡有一個function-foo,裡面有一個local object(m).在compiler時,就會決定了其local object
的大小(從其type,一般有2/4byte).而當complier 處理函數foo時,則會產生 sub sp,4 
(針對其local變數)
------------------- 
Allocating automatic storage for several local objects costs more stack space, but no more run time, than allocating storage for just one. For example, in:

int foo(int v) 
   { 
   int m;
   double d;
   ... 
   return m + n; 
   }
-------------
當其local object有多個時,其並不是一個一個建立的,故不會花更多的時間去建立storage.

------------- 
the function has two local objects, m and d. In this case, when it compiles the function, the compiler determines the size of m, still 4, and the size of d, say 8. Rather than generate a separate instruction to allocate storage for each object, the compiler simply adds up the sizes and uses the sum in a single instruction, such as:

sub sp, 12
---------------
在此有二個local object,(m,d),當此function被compiler處理時,其compiler會決定好其
每個object的大小,但並不是各別個自地allocate storage.而是一次處理之
--------------- 
A function may also declare local objects in nested blocks. For example, in:

int foo(int n)
    {
    char *p;
    ...
    if (p != NULL)
        {
        int v;
        ...
        }
    return n;
    }
-----------------
當在nested blocks中來宣告local object時
----------------- 
function foo has a block nested within the if statement. That block declares a local object v. In this case, the lifetime of the storage for v begins upon entry into the nested block and ends upon exiting the block. However, many compilers will generate code for foo to allocate the storage for v along with all the other local objects upon entering the function and deallocate the storage for v upon exiting foo.
------------------------------
在此中,有一個判斷式中又含有一個nested block ,而且裡面又有宣告一個local object v.
在這個例子中,其對於 物件 v 的存儲空間之lifetime是開始於進入到這個nested block並在
離開此一nested block後結束.
但是對於於compiler來講,它會在進入此一function中,就會產生一個對應於object v的 storage
及其它相關變數的.;然後在離開此一function後,就會結束其lifetime.
------------------------------
Thus, a compiler might generate code that extends the actual lifetime of the storage for a local object, but it's very hazardous for programs to try to exploit these longer lifetimes.
Dynamic allocation is typically much slower than automatic allocation. It often involves executing tens of instructions, possibly more than a hundred. Nonetheless, you can use it to manage memory very economically, and so it may be worth the price.
-------------------
因此,對compiler可能會產生多餘的程式碼,尤其是對於loacl object中的lifetime(compiler會延長其local 的lifetime),但是若要利用這些多出來的lifetime是很危險的.

Dynamic allocation一般比allocation automatic object慢上許多.因為它通當要執行一些指令才可以. 但它是比較有效率的利用memory的.
------------------- 
Linkage on the horizon
As I mentioned earlier, not only can a declaration specify type, scope, and storage duration, it can also specify linkage. I thought linkage would be the subject of this column until I started writing and realized that I needed to cover storage duration first. I'll get there yet.









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

沒有留言:

張貼留言