• Aucun résultat trouvé

Type Definitions

Dans le document III CP·6 (Page 92-99)

Syntax:

typedef-name:

identifier Semantics:

In a declaration whose storage-class specifier is typedef, each declarator defines an identifier to be a typedef name that specifies the type specified for the identifier in the way described at the beginning of this section. A typedef declaration does not introduce a new type, only a synonym for the type so specified. That is, in the following declarations:

typedef T type_ident;

type_ident D;

type_ident is defined as a typedef name with the type specified by the declaration specifiers in T (known as T), and the identifier in D has the type "derived-declarator-type-li5t T" where the derived-declarator-type-li5t is specified by the declarators of D. A typedef name shares the same name space as other identifiers declared in ordinary declarators. If the identifier is redeclared in an inner scope or is declared as a member of a structure or union in the same or an inner scope, the type specifiers cannot be omitted in the inner declaration.

Examples:

After

typedef int MILES, KLICKSP();

typedef struct { double reJ im; } complex;

the constructions

MILES distance;

extern KLICKSP *metricp;

complex Xi complex z, *zp;

are all valid declarations. The type of distance is int, that of metricp is "pointer to function with no parameter specification returning int" , and that of x and z is the specified structure; zp is a pointer to such a structure. The object distance has a type compatible with any other int object.

After the declarations

typedef 5truct sl { int Xi } tl, *tpl;

typedef struct s2 { int Xi } t2, *tp2;

type tl and the type pointed to by tpl are compatible. Type tl is also compatible with type struct sl, but is not compatible with the types struct 52, t2, the type pointed to by tp2, and into

5-16 Type Definitions HA17-00

The following obscure constructions: unnamed parameter with type pointer to function returning signed int with one unnamed parameter with type signed int", and an identifier t with type long.

On the other hand, typedef names can be used to improve code readability. All three of the following declarations of the signal function specify exactly the same type, the first without making use of any typedef names:

typedef void fv(int)j

Data Declarations

If the declaration of an identifier has block scope, and the identifier has external or internal linkage, the declaration may not have an initializer for the identifier.

Semantics:

An initializer specifies the initial value stored in an object.

All unnamed structure or union members are ignored during initialization.

If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant. If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

The initializer for a scalar is a single expression, optionally enclosed in braces. The initial . value of the object is that of the expression; the same type constraints and conversions as

for simple assignment apply.

A brace-enclosed initializer for a union object initializes the member that appears first in the declaration list of the union type.

The initializer for a structure or union object that has automatic storage duration is either an initializer list as described below, or is a single expression that has compatible structure or union type. In the latter case, the initial value of the object is that of the expression.

The rest of this section deals with initializers for objects that have aggregate or union type.

An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

An array with element type compatible with vchar _ t may be initialized by a wide string literal, optionally enclosed in braces. Successive codes of the wide string literal (including the terminating zero-valued code if there is room or if the array is of unknown size) initialize the elements of the array.

Otherwise, the initializer for an object that has aggregate type is a brace-enclosed list of initializers for the members of the aggregate, written in increasing subscript or member order. The initializer for an object that has union type is a brace-enclosed initializer for the first member of the union.

If the aggregate contains members that are aggregates or unions, or if the first member of a union is an aggregate or union, the rules apply recursively to the subaggregates or

5-18 Initialization HA17-00

Data Declarations contained unions. If the initializer of a subaggregate or contained union begins with a left brace, the initializers enclosed by that brace and its matching right brace initialize the members of the subaggregate or the first member of the contained union. Otherwise, only enough initializers from the list are taken to account for the members of the subaggregate or the first member of the contained union. Any remaining initializers are left to initialize the next member of the aggregate of which the current sub aggregate or contained union is a part.

If there are fewer initializers in a brace-enclosed list than there are members of an aggregate, the remainder of the aggregate is initialized implicitly the same as objects that have static storage duration.

If an array of unknown size is initialized, its size is determined by the number of initializers provided for its elements. At the end of its initializer list, the array no longer has incomplete type.

Examples:

The declaration

int x[]

= {

1, 3, 5 };

defines and initializes x as a one-dimensional array object that has three elements, as no size was specified and there are three initializers.

float y[4] [3]

=

{

{ 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 }, };

is a definition with a fully bracketed initialization: 1, 3, and 5 initialize the first row of y (the array object y [0]), namely y [0] [0], y [0] [1], and y [0] [2]. Likewise the next two lines initialize y [1] and y [2]. The initializer ends early, so y [3] is initialized with zeros.

Precisely the same effect could have been achieved by:

float y[4] [3]

= {

1, 3, 5, 2, 4, 6, 3, 5, 7 };

The initializer for y [0] does not begin with a left brace, so three items from the list are used. Likewise the next three are taken successively for y [1] and y [2]. Also,

float z[4] [3]

= {

{ 1 }, { 2 }, { 3 }, { 4 } };

initializes the first column of z as specified and initializes the rest with zeros.

struct { int a[3] , b; } v[]

= { {

1 }, 2 };

HA17-00 Initialization 5-19

Data Declarations

is a definition with an inconsistently bracketed but legal initialization. It defines an array with two element structures: il [0] . a [0] is 1 and 'W [lJ . a

[oJ

is 2; all the other elements

contains an incompletely but consistently bracketed initialization. It defines a three-dimensional array object: q [0] [0] [0] is 1, q [1] [0] [0] is 2, q [1] [0] [1] is 3, and 4,

Note that the fully-bracketed and minimally-bracketed forms of initialization are, In general, less likely to cause confusion.

Finally, the declaration

char s []

=

"abc", t [3]

=

"abc";

5-20 Initialization HA17-00

Data Declarations defines "plain" char array objects sand t whose elements are initialized with character string literals. This declaration is identical to

char s [J = { ) a), ) b), ) C ) , ) \ 0) }, t [J

= { )

a), ) b), ) c) };

The contents of the arrays are modifiable. On the other hand, the declaration char *P

=

"abc";

defines P with type "pointer to char" that is initialized to point to an object with type

"array of char" with length 4 whose elements are initialized with a character string literal.

If any attempt is made to use p to modify the contents of the array, the SIGSEGV signal is raised. The compilation option STRING=WRITEABLE allows strings to be overwritten.

HA17-00 Initialization 5-21

Section 6 Statements

This section describes the statement types of the C language: labeled, compound, expression and null, selection, iteration, and jump. For each statement type or statement, syntax, constraints, semantics, and examples are presented where appropriate.

Syntax:

8tatement:

labeled-8tatement compound-8tatement expre88ion-8tatement 8election-8tatement iteration-8tatement jump-8tatement Semantics:

A 8tatement specifies an action to be performed. Except as indicated, statements are executed in sequence.

A full e:cpre88ion is an expression that is not part of another expression. Each of the following is a full expression: an initializer, the expression in an expression statement, the controlling expression of a selection statement (if or switch), the controlling expression of a while or do statement, each of the three (optional) expressions of a for statement, and the (optional) expression in a return statement.

Dans le document III CP·6 (Page 92-99)