6.2 Concepts

6.2.1 Scopes of identifiers
1 An identifier can denote an object; a function; a tag or a member of a structure, union, or
enumeration; a typedef name; a label name; a macro name; or a macro parameter. The
same identifier can denote different entities at different points in the program. A member
of an enumeration is called an enumeration constant. Macro names and macro
parameters are not considered further here, because prior to the semantic phase of
program translation any occurrences of macro names in the source file are replaced by the
preprocessing token sequences that constitute their macro definitions.
2 For each different entity that an identifier designates, the identifier is visible (i.e., can be
used) only within a region of program text called its scope. Different entities designated
by the same identifier either have different scopes, or are in different name spaces. There
are four kinds of scopes: function, file, block, and function prototype. (A function
prototype is a declaration of a function that declares the types of its parameters.)
3 A label name is the only kind of identifier that has function scope. It can be used (in a
goto statement) anywhere in the function in which it appears, and is declared implicitly
by its syntactic appearance (followed by a : and a statement).
4 Every other identifier has scope determined by the placement of its declaration (in a
declarator or type specifier). If the declarator or type specifier that declares the identifier
appears outside of any block or list of parameters, the identifier has file scope, which
terminates at the end of the translation unit. If the declarator or type specifier that
declares the identifier appears inside a block or within the list of parameter declarations in
a function definition, the identifier has block scope, which terminates at the end of the
associated block. If the declarator or type specifier that declares the identifier appears

within the list of parameter declarations in a function prototype (not part of a function
definition), the identifier has function prototype scope, which terminates at the end of the
function declarator. If an identifier designates two different entities in the same name
space, the scopes might overlap. If so, the scope of one entity (the inner scope) will be a
strict subset of the scope of the other entity (the outer scope). Within the inner scope, the
identifier designates the entity declared in the inner scope; the entity declared in the outer
scope is hidden (and not visible) within the inner scope.
5 Unless explicitly stated otherwise, where this International Standard uses the term
‘‘identifier’’ to refer to some entity (as opposed to the syntactic construct), it refers to the
entity in the relevant name space whose declaration is visible at the point the identifier
occurs.
6 Tw o identifiers have the same scope if and only if their scopes terminate at the same
point.
7 Structure, union, and enumeration tags have scope that begins just after the appearance of
the tag in a type specifier that declares the tag. Each enumeration constant has scope that
begins just after the appearance of its defining enumerator in an enumerator list. Any
other identifier has scope that begins just after the completion of its declarator.
Forward references: declarations (6.7), function calls (6.5.2.2), function definitions
(6.9.1), identifiers (6.4.2), name spaces of identifiers (6.2.3), macro replacement (6.10.3),
source file inclusion (6.10.2), statements (6.8).

6.2.2 Linkages of identifiers
1 An identifier declared in different scopes or in the same scope more than once can be
made to refer to the same object or function by a process called linkage.21) There are
three kinds of linkage: external, internal, and none.
2 In the set of translation units and libraries that constitutes an entire program, each
declaration of a particular identifier with external linkage denotes the same object or
function. Within one translation unit, each declaration of an identifier with internal
linkage denotes the same object or function. Each declaration of an identifier with no
linkage denotes a unique entity.
3 If the declaration of a file scope identifier for an object or a function contains the storageclass
specifier static, the identifier has internal linkage.22)
4 For an identifier declared with the storage-class specifier extern in a scope in which aprior declaration of that identifier is visible,23) if the prior declaration specifies internal or
external linkage, the linkage of the identifier at the later declaration is the same as the
linkage specified at the prior declaration. If no prior declaration is visible, or if the prior
declaration specifies no linkage, then the identifier has external linkage.
5 If the declaration of an identifier for a function has no storage-class specifier, its linkage
is determined exactly as if it were declared with the storage-class specifier extern. If
the declaration of an identifier for an object has file scope and no storage-class specifier,
its linkage is external.
6 The following identifiers have no linkage: an identifier declared to be anything other than
an object or a function; an identifier declared to be a function parameter; a block scope
identifier for an object declared without the storage-class specifier extern.
7 If, within a translation unit, the same identifier appears with both internal and external
linkage, the behavior is undefined.
Forward references: declarations (6.7), expressions (6.5), external definitions (6.9),
statements (6.8).
6.2.3 Name spaces of identifiers
1 If more than one declaration of a particular identifier is visible at any point in a
translation unit, the syntactic context disambiguates uses that refer to different entities.
Thus, there are separate name spaces for various categories of identifiers, as follows:
— label names (disambiguated by the syntax of the label declaration and use);
— the tags of structures, unions, and enumerations (disambiguated by following any24)
of the keywords struct, union, or enum);
— the members of structures or unions; each structure or union has a separate name
space for its members (disambiguated by the type of the expression used to access the
member via the . or -> operator);
— all other identifiers, called ordinary identifiers (declared in ordinary declarators or as
enumeration constants).
Forward references: enumeration specifiers (6.7.2.2), labeled statements (6.8.1),
structure and union specifiers (6.7.2.1), structure and union members (6.5.2.3), tags
(6.7.2.3), the goto statement (6.8.6.1).

6.2.4 Storage durations of objects
1 An object has a storage duration that determines its lifetime. There are three storage
durations: static, automatic, and allocated. Allocated storage is described in 7.20.3.
2 The lifetime of an object is the portion of program execution during which storage is
guaranteed to be reserved for it. An object exists, has a constant address,25) and retains
its last-stored value throughout its lifetime.26) If an object is referred to outside of its
lifetime, the behavior is undefined. The value of a pointer becomes indeterminate when
the object it points to reaches the end of its lifetime.
3 An object whose identifier is declared with external or internal linkage, or with the
storage-class specifier static has static storage duration. Its lifetime is the entire
execution of the program and its stored value is initialized only once, prior to program
startup.
4 An object whose identifier is declared with no linkage and without the storage-class
specifier static has automatic storage duration.
5 For such an object that does not have a variable length array type, its lifetime extends
from entry into the block with which it is associated until execution of that block ends in
any way. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate. If an
initialization is specified for the object, it is performed each time the declaration is
reached in the execution of the block; otherwise, the value becomes indeterminate each
time the declaration is reached.
6 For such an object that does have a variable length array type, its lifetime extends from
the declaration of the object until execution of the program leaves the scope of the
declaration.27) If the scope is entered recursively, a new instance of the object is created
each time. The initial value of the object is indeterminate.
Forward references: statements (6.8), function calls (6.5.2.2), declarators (6.7.5), array
declarators (6.7.5.2), initialization (6.7.8).

6.2.5 Types
1 The meaning of a value stored in an object or returned by a function is determined by the
type of the expression used to access it. (An identifier declared to be an object is the
simplest such expression; the type is specified in the declaration of the identifier.) Types
are partitioned into object types (types that fully describe objects), function types (types
that describe functions), and incomplete types (types that describe objects but lack
information needed to determine their sizes).
2 An object declared as type _Bool is large enough to store the values 0 and 1.
3 An object declared as type char is large enough to store any member of the basic
execution character set. If a member of the basic execution character set is stored in a
char object, its value is guaranteed to be positive. If any other character is stored in a
char object, the resulting value is implementation-defined but shall be within the range
of values that can be represented in that type.
4 There are five standard signed integer types, designated as signed char, short
int, int, long int, and long long int. (These and other types may be
designated in several additional ways, as described in 6.7.2.) There may also be
implementation-defined extended signed integer types.28) The standard and extended
signed integer types are collectively called signed integer types.29)
5 An object declared as type signed char occupies the same amount of storage as a
‘‘plain’’ char object. A ‘‘plain’’ int object has the natural size suggested by the
architecture of the execution environment (large enough to contain any value in the range
INT_MIN to INT_MAX as defined in the header <limits.h>).
6 For each of the signed integer types, there is a corresponding (but different) unsigned
integer type (designated with the keyword unsigned) that uses the same amount of
storage (including sign information) and has the same alignment requirements. The type
_Bool and the unsigned integer types that correspond to the standard signed integer
types are the standard unsigned integer types. The unsigned integer types that
correspond to the extended signed integer types are the extended unsigned integer types.
The standard and extended unsigned integer types are collectively called unsigned integer
types.30)7 The standard signed integer types and standard unsigned integer types are collectively
called the standard integer types, the extended signed integer types and extended
unsigned integer types are collectively called the extended integer types.
8 For any two integer types with the same signedness and different integer conversion rank
(see 6.3.1.1), the range of values of the type with smaller integer conversion rank is a
subrange of the values of the other type.
9 The range of nonnegative values of a signed integer type is a subrange of the
corresponding unsigned integer type, and the representation of the same value in each
type is the same.31) A computation involving unsigned operands can never overflow,
because a result that cannot be represented by the resulting unsigned integer type is
reduced modulo the number that is one greater than the largest value that can be
represented by the resulting type.
10 There are three real floating types, designated as float, double, and long
double.32) The set of values of the type float is a subset of the set of values of the
type double; the set of values of the type double is a subset of the set of values of the
type long double.
11 There are three complex types, designated as float _Complex, double
_Complex, and long double _Complex.33) The real floating and complex types
are collectively called the floating types.
12 For each floating type there is a corresponding real type, which is always a real floating
type. For real floating types, it is the same type. For complex types, it is the type given
by deleting the keyword _Complex from the type name.
13 Each complex type has the same representation and alignment requirements as an array
type containing exactly two elements of the corresponding real type; the first element is
equal to the real part, and the second element to the imaginary part, of the complex
number.
14 The type char, the signed and unsigned integer types, and the floating types are
collectively called the basic types. Even if the implementation defines two or more basic
types to have the same representation, they are nevertheless different types.34)

15 The three types char, signed char, and unsigned char are collectively called
the character types. The implementation shall define char to have the same range,
representation, and behavior as either signed char or unsigned char.35)
16 An enumeration comprises a set of named integer constant values. Each distinct
enumeration constitutes a different enumerated type.
17 The type char, the signed and unsigned integer types, and the enumerated types are
collectively called integer types. The integer and real floating types are collectively called
real types.
18 Integer and floating types are collectively called arithmetic types. Each arithmetic type
belongs to one type domain: the real type domain comprises the real types, the complex
type domain comprises the complex types.
19 The void type comprises an empty set of values; it is an incomplete type that cannot be
completed.
20 Any number of derived types can be constructed from the object, function, and
incomplete types, as follows:
— An array type describes a contiguously allocated nonempty set of objects with a
particular member object type, called the element type.36) Array types are
characterized by their element type and by the number of elements in the array. An
array type is said to be derived from its element type, and if its element type is T, the
array type is sometimes called ‘‘array of T’’. The construction of an array type from
an element type is called ‘‘array type derivation’’.
— A structure type describes a sequentially allocated nonempty set of member objects
(and, in certain circumstances, an incomplete array), each of which has an optionally
specified name and possibly distinct type.
— A union type describes an overlapping nonempty set of member objects, each of
which has an optionally specified name and possibly distinct type.
— A function type describes a function with specified return type. A function type is
characterized by its return type and the number and types of its parameters. A
function type is said to be derived from its return type, and if its return type is T, the
function type is sometimes called ‘‘function returning T’’. The construction of a
function type from a return type is called ‘‘function type derivation’’.

— Apointer type may be derived from a function type, an object type, or an incomplete
type, called the referenced type. A pointer type describes an object whose value
provides a reference to an entity of the referenced type. A pointer type derived from
the referenced type T is sometimes called ‘‘pointer to T’’. The construction of a
pointer type from a referenced type is called ‘‘pointer type derivation’’.
These methods of constructing derived types can be applied recursively.
21 Arithmetic types and pointer types are collectively called scalar types. Array and
structure types are collectively called aggregate types.37)
22 An array type of unknown size is an incomplete type. It is completed, for an identifier of
that type, by specifying the size in a later declaration (with internal or external linkage).
A structure or union type of unknown content (as described in 6.7.2.3) is an incomplete
type. It is completed, for all declarations of that type, by declaring the same structure or
union tag with its defining content later in the same scope.
23 Array, function, and pointer types are collectively called derived declarator types. A
declarator type derivation from a type T is the construction of a derived declarator type
from T by the application of an array-type, a function-type, or a pointer-type derivation to
T.
24 A type is characterized by its type category, which is either the outermost derivation of a
derived type (as noted above in the construction of derived types), or the type itself if the
type consists of no derived types.
25 Any type so far mentioned is an unqualified type. Each unqualified type has several
qualified versions of its type,38) corresponding to the combinations of one, two, or all
three of the const, volatile, and restrict qualifiers. The qualified or unqualified
versions of a type are distinct types that belong to the same type category and have the
same representation and alignment requirements.39) A derived type is not qualified by the
qualifiers (if any) of the type from which it is derived.
26 A pointer to void shall have the same representation and alignment requirements as a
pointer to a character type.39) Similarly, pointers to qualified or unqualified versions of
compatible types shall have the same representation and alignment requirements. All
pointers to structure types shall have the same representation and alignment requirements
as each other. All pointers to union types shall have the same representation and
alignment requirements as each other. Pointers to other types need not have the same

representation or alignment requirements.
27 EXAMPLE 1 The type designated as ‘‘float *’’ has type ‘‘pointer to float’’. Its type category is
pointer, not a floating type. The const-qualified version of this type is designated as ‘‘float * const’’
whereas the type designated as ‘‘const float *’’ is not a qualified type — its type is ‘‘pointer to constqualified
float’’ and is a pointer to a qualified type.
28 EXAMPLE 2 The type designated as ‘‘struct tag (*[5])(float)’’ has type ‘‘array of pointer to
function returning struct tag’’. The array has length five and the function has a single parameter of type
float. Its type category is array.
Forward references: compatible type and composite type (6.2.7), declarations (6.7).
6.2.6 Representations of types
6.2.6.1 General
1 The representations of all types are unspecified except as stated in this subclause.
2 Except for bit-fields, objects are composed of contiguous sequences of one or more bytes,
the number, order, and encoding of which are either explicitly specified or
implementation-defined.
3 Values stored in unsigned bit-fields and objects of type unsigned char shall be
represented using a pure binary notation.40)
4 Values stored in non-bit-field objects of any other object type consist of n ´ CHAR_BIT
bits, where n is the size of an object of that type, in bytes. The value may be copied into
an object of type unsigned char [n] (e.g., by memcpy); the resulting set of bytes is
called the object representation of the value. Values stored in bit-fields consist of m bits,
where m is the size specified for the bit-field. The object representation is the set of m
bits the bit-field comprises in the addressable storage unit holding it. Tw o values (other
than NaNs) with the same object representation compare equal, but values that compare
equal may have different object representations.
5 Certain object representations need not represent a value of the object type. If the stored
value of an object has such a representation and is read by an lvalue expression that does
not have character type, the behavior is undefined. If such a representation is produced
by a side effect that modifies all or any part of the object by an lvalue expression that
does not have character type, the behavior is undefined.41) Such a representation is called
a trap representation.

 6 When a value is stored in an object of structure or union type, including in a member
object, the bytes of the object representation that correspond to any padding bytes take
unspecified values.42) The values of padding bytes shall not affect whether the value of
such an object is a trap representation. Those bits of a structure or union object that are
in the same byte as a bit-field member, but are not part of that member, shall similarly not
affect whether the value of such an object is a trap representation.
7 When a value is stored in a member of an object of union type, the bytes of the object
representation that do not correspond to that member but do correspond to other members
take unspecified values, but the value of the union object shall not thereby become a trap
representation.
8 Where an operator is applied to a value that has more than one object representation,
which object representation is used shall not affect the value of the result.43) Where a
value is stored in an object using a type that has more than one object representation for
that value, it is unspecified which representation is used, but a trap representation shall
not be generated.
Forward references: declarations (6.7), expressions (6.5), lvalues, arrays, and function
designators (6.3.2.1).
6.2.6.2 Integer types
1 For unsigned integer types other than unsigned char, the bits of the object
representation shall be divided into two groups: value bits and padding bits (there need
not be any of the latter). If there are N value bits, each bit shall represent a different
power of 2 between 1 and 2N-1, so that objects of that type shall be capable of
representing values from 0 to 2N - 1 using a pure binary representation; this shall be
known as the value representation. The values of any padding bits are unspecified.44)
2 For signed integer types, the bits of the object representation shall be divided into three
groups: value bits, padding bits, and the sign bit. There need not be any padding bits;
there shall be exactly one sign bit. Each bit that is a value bit shall have the same value as

the same bit in the object representation of the corresponding unsigned type (if there are
M value bits in the signed type and N in the unsigned type, then M £ N). If the sign bit
is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be
modified in one of the following ways:
— the corresponding value with sign bit 0 is negated (sign and magnitude);
— the sign bit has the value -(2N) (two’s complement);
— the sign bit has the value -(2N - 1) (one’s complement).
Which of these applies is implementation-defined, as is whether the value with sign bit 1
and all value bits zero (for the first two), or with sign bit and all value bits 1 (for one’s
complement), is a trap representation or a normal value. In the case of sign and
magnitude and one’s complement, if this representation is a normal value it is called a
negative zero.
3 If the implementation supports negative zeros, they shall be generated only by:
— the &, |, ^, ~, <<, and >> operators with arguments that produce such a value;
— the +, -, *, /, and % operators where one argument is a negative zero and the result is
zero;
— compound assignment operators based on the above cases.
It is unspecified whether these cases actually generate a negative zero or a normal zero,
and whether a negative zero becomes a normal zero when stored in an object.
4 If the implementation does not support negative zeros, the behavior of the &, |, ^, ~, <<,
and >> operators with arguments that would produce such a value is undefined.
5 The values of any padding bits are unspecified.45) A valid (non-trap) object representation
of a signed integer type where the sign bit is zero is a valid object representation of the
corresponding unsigned type, and shall represent the same value.
6 The precision of an integer type is the number of bits it uses to represent values,
excluding any sign and padding bits. The width of an integer type is the same but
including any sign bit; thus for unsigned integer types the two values are the same, while
for signed integer types the width is one greater than the precision.

6.2.7 Compatible type and composite type
1 Tw o types have compatible type if their types are the same. Additional rules for
determining whether two types are compatible are described in 6.7.2 for type specifiers,
in 6.7.3 for type qualifiers, and in 6.7.5 for declarators.46) Moreover, two structure,
union, or enumerated types declared in separate translation units are compatible if their
tags and members satisfy the following requirements: If one is declared with a tag, the
other shall be declared with the same tag. If both are complete types, then the following
additional requirements apply: there shall be a one-to-one correspondence between their
members such that each pair of corresponding members are declared with compatible
types, and such that if one member of a corresponding pair is declared with a name, the
other member is declared with the same name. For two structures, corresponding
members shall be declared in the same order. For two structures or unions, corresponding
bit-fields shall have the same widths. For two enumerations, corresponding members
shall have the same values.
2 All declarations that refer to the same object or function shall have compatible type;
otherwise, the behavior is undefined.
3 Acomposite type can be constructed from two types that are compatible; it is a type that
is compatible with both of the two types and satisfies the following conditions:
— If one type is an array of known constant size, the composite type is an array of that
size; otherwise, if one type is a variable length array, the composite type is that type.
— If only one type is a function type with a parameter type list (a function prototype),
the composite type is a function prototype with the parameter type list.
— If both types are function types with parameter type lists, the type of each parameter
in the composite parameter type list is the composite type of the corresponding
parameters.
These rules apply recursively to the types from which the two types are derived.
4 For an identifier with internal or external linkage declared in a scope in which a prior
declaration of that identifier is visible,47) if the prior declaration specifies internal or
external linkage, the type of the identifier at the later declaration becomes the composite
type.5 EXAMPLE Given the following two file scope declarations:
int f(int (*)(), double (*)[3]);
int f(int (*)(char *), double (*)[]);
The resulting composite type for the function is:
int f(int (*)(char *), double (*)[3]);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值