Стандарт языка Си С99 TC (1113411), страница 19
Текст из файла (страница 19)
If the compound literal occurs outside the body of a function, the objecthas static storage duration; otherwise, it has automatic storage duration associated withthe enclosing block.7All the semantic rules and constraints for initializer lists in 6.7.8 are applicable tocompound literals.85)8String literals, and compound literals with const-qualified types, need not designatedistinct objects.86)9EXAMPLE 1The file scope definitionint *p = (int []){2, 4};initializes p to point to the first element of an array of two ints, the first having the value two and thesecond, four. The expressions in this compound literal are required to be constant.
The unnamed objecthas static storage duration.10EXAMPLE 2In contrast, invoid f(void){int *p;/*...*/p = (int [2]){*p};/*...*/}p is assigned the address of the first element of an array of two ints, the first having the value previouslypointed to by p and the second, zero. The expressions in this compound literal need not be constant. Theunnamed object has automatic storage duration.11EXAMPLE 3 Initializers with designations can be combined with compound literals. Structure objectscreated using compound literals can be passed to functions without depending on member order:drawline((struct point){.x=1, .y=1},(struct point){.x=3, .y=4});Or, if drawline instead expected pointers to struct point:drawline(&(struct point){.x=1, .y=1},&(struct point){.x=3, .y=4});12EXAMPLE 4A read-only compound literal can be specified through constructions like:(const float []){1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6}85) For example, subobjects without explicit initializers are initialized to zero.86) This allows implementations to share storage for string literals and constant compound literals withthe same or overlapping representations.76Language§6.5.2.5WG14/N125613EXAMPLE 5Committee Draft — Septermber 7, 2007ISO/IEC 9899:TC3The following three expressions have different meanings:"/tmp/fileXXXXXX"(char []){"/tmp/fileXXXXXX"}(const char []){"/tmp/fileXXXXXX"}The first always has static storage duration and has type array of char, but need not be modifiable; the lasttwo have automatic storage duration when they occur within the body of a function, and the first of thesetwo is modifiable.14EXAMPLE 6 Like string literals, const-qualified compound literals can be placed into read-only memoryand can even be shared.
For example,(const char []){"abc"} == "abc"might yield 1 if the literals’ storage is shared.15EXAMPLE 7 Since compound literals are unnamed, a single compound literal cannot specify a circularlylinked object. For example, there is no way to write a self-referential compound literal that could be usedas the function argument in place of the named object endless_zeros below:struct int_list { int car; struct int_list *cdr; };struct int_list endless_zeros = {0, &endless_zeros};eval(endless_zeros);16EXAMPLE 8Each compound literal creates only a single object in a given scope:struct s { int i; };int f (void){struct s *p = 0, *q;int j = 0;again:q = p, p = &((struct s){ j++ });if (j < 2) goto again;return p == q && q->i == 1;}The function f() always returns the value 1.17Note that if an iteration statement were used instead of an explicit goto and a labeled statement, thelifetime of the unnamed object would be the body of the loop only, and on entry next time around p wouldhave an indeterminate value, which would result in undefined behavior.Forward references: type names (6.7.6), initialization (6.7.8).§6.5.2.5Language77ISO/IEC 9899:TC3Committee Draft — Septermber 7, 2007WG14/N12566.5.3 Unary operatorsSyntax1unary-expression:postfix-expression++ unary-expression-- unary-expressionunary-operator cast-expressionsizeof unary-expressionsizeof ( type-name )unary-operator: one of& * + - ~!6.5.3.1 Prefix increment and decrement operatorsConstraints1The operand of the prefix increment or decrement operator shall have qualified orunqualified real or pointer type and shall be a modifiable lvalue.Semantics2The value of the operand of the prefix ++ operator is incremented.
The result is the newvalue of the operand after incrementation. The expression ++E is equivalent to (E+=1).See the discussions of additive operators and compound assignment for information onconstraints, types, side effects, and conversions and the effects of operations on pointers.3The prefix -- operator is analogous to the prefix ++ operator, except that the value of theoperand is decremented.Forward references: additive operators (6.5.6), compound assignment (6.5.16.2).6.5.3.2 Address and indirection operatorsConstraints1The operand of the unary & operator shall be either a function designator, the result of a[] or unary * operator, or an lvalue that designates an object that is not a bit-field and isnot declared with the register storage-class specifier.2The operand of the unary * operator shall have pointer type.Semantics3The unary & operator yields the address of its operand.
If the operand has type ‘‘type’’,the result has type ‘‘pointer to type’’. If the operand is the result of a unary * operator,neither that operator nor the & operator is evaluated and the result is as if both wereomitted, except that the constraints on the operators still apply and the result is not anlvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor78Language§6.5.3.2WG14/N1256Committee Draft — Septermber 7, 2007ISO/IEC 9899:TC3the unary * that is implied by the [] is evaluated and the result is as if the & operatorwere removed and the [] operator were changed to a + operator.
Otherwise, the result isa pointer to the object or function designated by its operand.4The unary * operator denotes indirection. If the operand points to a function, the result isa function designator; if it points to an object, the result is an lvalue designating theobject. If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If aninvalid value has been assigned to the pointer, the behavior of the unary * operator isundefined.87)Forward references: storage-class specifiers (6.7.1), structure and union specifiers(6.7.2.1).6.5.3.3 Unary arithmetic operatorsConstraints1The operand of the unary + or - operator shall have arithmetic type; of the ~ operator,integer type; of the ! operator, scalar type.Semantics2The result of the unary + operator is the value of its (promoted) operand. The integerpromotions are performed on the operand, and the result has the promoted type.3The result of the unary - operator is the negative of its (promoted) operand.
The integerpromotions are performed on the operand, and the result has the promoted type.4The result of the ~ operator is the bitwise complement of its (promoted) operand (that is,each bit in the result is set if and only if the corresponding bit in the converted operand isnot set). The integer promotions are performed on the operand, and the result has thepromoted type. If the promoted type is an unsigned type, the expression ~E is equivalentto the maximum value representable in that type minus E.5The result of the logical negation operator ! is 0 if the value of its operand comparesunequal to 0, 1 if the value of its operand compares equal to 0. The result has type int.The expression !E is equivalent to (0==E).87) Thus, &*E is equivalent to E (even if E is a null pointer), and &(E1[E2]) to ((E1)+(E2)).
It isalways true that if E is a function designator or an lvalue that is a valid operand of the unary &operator, *&E is a function designator or an lvalue equal to E. If *P is an lvalue and T is the name ofan object pointer type, *(T)P is an lvalue that has a type compatible with that to which T points.Among the invalid values for dereferencing a pointer by the unary * operator are a null pointer, anaddress inappropriately aligned for the type of object pointed to, and the address of an object after theend of its lifetime.§6.5.3.3Language79ISO/IEC 9899:TC3Committee Draft — Septermber 7, 2007WG14/N12566.5.3.4 The sizeof operatorConstraints1The sizeof operator shall not be applied to an expression that has function type or anincomplete type, to the parenthesized name of such a type, or to an expression thatdesignates a bit-field member.Semantics2The sizeof operator yields the size (in bytes) of its operand, which may be anexpression or the parenthesized name of a type.
The size is determined from the type ofthe operand. The result is an integer. If the type of the operand is a variable length arraytype, the operand is evaluated; otherwise, the operand is not evaluated and the result is aninteger constant.3When applied to an operand that has type char, unsigned char, or signed char,(or a qualified version thereof) the result is 1. When applied to an operand that has arraytype, the result is the total number of bytes in the array.88) When applied to an operandthat has structure or union type, the result is the total number of bytes in such an object,including internal and trailing padding.4The value of the result is implementation-defined, and its type (an unsigned integer type)is size_t, defined in <stddef.h> (and other headers).5EXAMPLE 1 A principal use of the sizeof operator is in communication with routines such as storageallocators and I/O systems.
A storage-allocation function might accept a size (in bytes) of an object toallocate and return a pointer to void. For example:extern void *alloc(size_t);double *dp = alloc(sizeof *dp);The implementation of the alloc function should ensure that its return value is aligned suitably forconversion to a pointer to double.6EXAMPLE 2Another use of the sizeof operator is to compute the number of elements in an array:sizeof array / sizeof array[0]7EXAMPLE 3function:In this example, the size of a variable length array is computed and returned from a#include <stddef.h>size_t fsize3(int n){char b[n+3];return sizeof b;}// variable length array// execution time sizeof88) When applied to a parameter declared to have array or function type, the sizeof operator yields thesize of the adjusted (pointer) type (see 6.9.1).80Language§6.5.3.4WG14/N1256Committee Draft — Septermber 7, 2007ISO/IEC 9899:TC3int main(){size_t size;size = fsize3(10); // fsize3 returns 13return 0;}Forward references: common definitions <stddef.h> (7.17), declarations (6.7),structure and union specifiers (6.7.2.1), type names (6.7.6), array declarators (6.7.5.2).6.5.4 Cast operatorsSyntax1cast-expression:unary-expression( type-name ) cast-expressionConstraints2Unless the type name specifies a void type, the type name shall specify qualified orunqualified scalar type and the operand shall have scalar type.3Conversions that involve pointers, other than where permitted by the constraints of6.5.16.1, shall be specified by means of an explicit cast.Semantics4Preceding an expression by a parenthesized type name converts the value of theexpression to the named type.
This construction is called a cast.89) A cast that specifiesno conversion has no effect on the type or value of an expression.5If the value of the expression is represented with greater precision or range than requiredby the type named by the cast (6.3.1.8), then the cast specifies a conversion even if thetype of the expression is the same as the named type.Forward references: equality operators (6.5.9), function declarators (includingprototypes) (6.7.5.3), simple assignment (6.5.16.1), type names (6.7.6).89) A cast does not yield an lvalue. Thus, a cast to a qualified type has the same effect as a cast to theunqualified version of the type.§6.5.4Language81ISO/IEC 9899:TC3Committee Draft — Septermber 7, 2007WG14/N12566.5.5 Multiplicative operatorsSyntax1multiplicative-expression:cast-expressionmultiplicative-expression * cast-expressionmultiplicative-expression / cast-expressionmultiplicative-expression % cast-expressionConstraints2Each of the operands shall have arithmetic type.