Programming languages — C (INTERNATIONAL STANDARD ISO/IEC 9899:TC3) - page 5

 

  Главная      Manuals     Programming languages — C (INTERNATIONAL STANDARD ISO/IEC 9899:TC3) - 2007 year

 

Search            copyright infringement  

 

 

 

 

 

 

 

 

 

 

 

Content      ..     3      4      5      6     ..

 

 

 

Programming languages — C (INTERNATIONAL STANDARD ISO/IEC 9899:TC3) - page 5

 

 

Constraints

9

The value of an octal or hexadecimal escape sequence shall be in the range of
representable values for the type

unsigned char

for an integer character constant, or

the unsigned type corresponding to

wchar_t

for a wide character constant.

Semantics

10

An integer character constant has type

int

. The value of an integer character constant

containing a single character that maps to a single-byte execution character is the
numerical value of the representation of the mapped character interpreted as an integer.
The value of an integer character constant containing more than one character (e.g.,

'ab'

), or containing a character or escape sequence that does not map to a single-byte

execution character, is implementation-defined. If an integer character constant contains
a single character or escape sequence, its value is the one that results when an object with
type

char

whose value is that of the single character or escape sequence is converted to

type

int

.

11

A wide character constant has type

wchar_t

, an integer type defined in the

<stddef.h>

header. The value of a wide character constant containing a single

multibyte character that maps to a member of the extended execution character set is the
wide character corresponding to that multibyte character, as defined by the

mbtowc

function, with an implementation-defined current locale. The value of a wide character
constant containing more than one multibyte character, or containing a multibyte
character or escape sequence not represented in the extended execution character set, is
implementation-defined.

12

EXAMPLE 1

The construction

'\0'

is commonly used to represent the null character.

13

EXAMPLE 2

Consider implementations that use two’s-complement representation for integers and eight

bits for objects that have type

char

. In an implementation in which type

char

has the same range of

values as

signed char

, the integer character constant

'\xFF'

has the value

−1

; if type

char

has the

same range of values as

unsigned char

, the character constant

'\xFF'

has the value

+255

.

14

EXAMPLE 3

Even if eight bits are used for objects that have type

char

, the construction

'\x123'

specifies an integer character constant containing only one character, since a hexadecimal escape sequence
is terminated only by a non-hexadecimal character. To specify an integer character constant containing the
two characters whose values are

'\x12'

and

'3'

, the construction

'\0223'

may be used, since an octal

escape sequence is terminated after three octal digits. (The value of this two-character integer character
constant is implementation-defined.)

15

EXAMPLE 4

Even if 12 or more bits are used for objects that have type

wchar_t

, the construction

L'\1234'

specifies the implementation-defined value that results from the combination of the values

0123

and

'4'

.

Forward references: common definitions

<stddef.h>

(7.17), the

mbtowc

function

(7.20.7.2).

§6.4.4.4 Language

61

6.4.5 String literals

Syntax

1

string-literal:

"

s-char-sequence

opt

"

L"

s-char-sequence

opt

"

s-char-sequence:

s-char
s-char-sequence s-char

s-char:

any member of the source character set except

the double-quote

"

, backslash

\

, or new-line character

escape-sequence

Description

2

character string literal is a sequence of zero or more multibyte characters enclosed in
double-quotes, as in

"xyz"

. A wide string literal is the same, except prefixed by the

letter

L

.

3

The same considerations apply to each element of the sequence in a character string
literal or a wide string literal as if it were in an integer character constant or a wide
character constant, except that the single-quote

'

is representable either by itself or by the

escape sequence

\'

, but the double-quote

"

shall be represented by the escape sequence

\"

.

Semantics

4

In translation phase 6, the multibyte character sequences specified by any sequence of
adjacent character and wide string literal tokens are concatenated into a single multibyte
character sequence. If any of the tokens are wide string literal tokens, the resulting
multibyte character sequence is treated as a wide string literal; otherwise, it is treated as a
character string literal.

5

In translation phase 7, a byte or code of value zero is appended to each multibyte
character sequence that results from a string literal or literals.

66)

The multibyte character

sequence is then used to initialize an array of static storage duration and length just
sufficient to contain the sequence. For character string literals, the array elements have
type

char

, and are initialized with the individual bytes of the multibyte character

sequence; for wide string literals, the array elements have type

wchar_t

, and are

initialized with the sequence of wide characters corresponding to the multibyte character

66) A character string literal need not be a string (see 7.1.1), because a null character may be embedded in

it by a

\0

escape sequence.

62 Language

§6.4.5

sequence, as defined by the

mbstowcs

function with an implementation-defined current

locale. The value of a string literal containing a multibyte character or escape sequence
not represented in the execution character set is implementation-defined.

6

It is unspecified whether these arrays are distinct provided their elements have the
appropriate values. If the program attempts to modify such an array, the behavior is
undefined.

7

EXAMPLE This pair of adjacent character string literals

"\x12" "3"

produces a single character string literal containing the two characters whose values are

'\x12'

and

'3'

,

because escape sequences are converted into single members of the execution character set just prior to
adjacent string literal concatenation.

Forward references:

common definitions

<stddef.h>

(7.17), the

mbstowcs

function (7.20.8.1).

6.4.6 Punctuators

Syntax

1

punctuator: one of

[

]

(

)

{

}

.

->

++ -- & * + - ~ !

/

%

<<

>>

<

>

<=

>=

==

!=

^

|

&&

||

?

:

;

...

=

*=

/=

%=

+=

-=

<<= >>= &= ^= |=

,

#

##

<: :> <% %> %: %:%:

Semantics

2

A punctuator is a symbol that has independent syntactic and semantic significance.
Depending on context, it may specify an operation to be performed (which in turn may
yield a value or a function designator, produce a side effect, or some combination thereof)
in which case it is known as an operator (other forms of operator also exist in some
contexts). An operand is an entity on which an operator acts.

§6.4.6 Language

63

3

In all aspects of the language, the six tokens

67)

<: :> <% %> %: %:%:

behave, respectively, the same as the six tokens

[

]

{

}

#

##

except for their spelling.

68)

Forward references: expressions (6.5), declarations (6.7), preprocessing directives
(6.10), statements (6.8).

6.4.7 Header names

Syntax

1

header-name:

<

h-char-sequence

>

"

q-char-sequence

"

h-char-sequence:

h-char
h-char-sequence h-char

h-char:

any member of the source character set except

the new-line character and

>

q-char-sequence:

q-char
q-char-sequence q-char

q-char:

any member of the source character set except

the new-line character and

"

Semantics

2

The sequences in both forms of header names are mapped in an implementation-defined
manner to headers or external source file names as specified in 6.10.2.

3

If the characters

'

,

\

,

"

,

//

, or

/*

occur in the sequence between the

<

and

>

delimiters,

the behavior is undefined. Similarly, if the characters

'

,

\

,

//

, or

/*

occur in the

67) These tokens are sometimes called ‘‘digraphs’’.

68) Thus

[

and

<:

behave differently when ‘‘stringized’’ (see 6.10.3.2), but can otherwise be freely

interchanged.

64 Language

§6.4.7

sequence between the

"

delimiters, the behavior is undefined.

69)

Header name

preprocessing tokens are recognized only within

#include

preprocessing directives and

in implementation-defined locations within

#pragma

directives.

70)

4

EXAMPLE The following sequence of characters:

0x3<1/a.h>1e2

#include <1/a.h>

#define const.member@$

forms the following sequence of preprocessing tokens (with each individual preprocessing token delimited
by a on the left and a on the right).

{

0x3

}{

<

}{

1

}{

/

}{

a

}{

.

}{

h

}{

>

}{

1e2

}

{

#

}{

include

} {

<1/a.h>

}

{

#

}{

define

} {

const

}{

.

}{

member

}{

@

}{

$

}

Forward references: source file inclusion (6.10.2).

6.4.8 Preprocessing numbers

Syntax

1

pp-number:

digit

.

digit

pp-number digit
pp-number identifier-nondigit
pp-number

e

sign

pp-number

E

sign

pp-number

p

sign

pp-number

P

sign

pp-number

.

Description

2

A preprocessing number begins with a digit optionally preceded by a period (

.

) and may

be followed by valid identifier characters and the character sequences

e+

,

e-

,

E+

,

E-

,

p+

,

p-

,

P+

, or

P-

.

3

Preprocessing number tokens lexically include all floating and integer constant tokens.

Semantics

4

A preprocessing number does not have type or a value; it acquires both after a successful
conversion (as part of translation phase 7) to a floating constant token or an integer
constant token.

69) Thus, sequences of characters that resemble escape sequences cause undefined behavior.

70) For an example of a header name preprocessing token used in a

#pragma

directive, see 6.10.9.

§6.4.8 Language

65

6.4.9 Comments

1

Except within a character constant, a string literal, or a comment, the characters

/*

introduce a comment. The contents of such a comment are examined only to identify
multibyte characters and to find the characters

*/

that terminate it.

71)

2

Except within a character constant, a string literal, or a comment, the characters

//

introduce a comment that includes all multibyte characters up to, but not including, the
next new-line character. The contents of such a comment are examined only to identify
multibyte characters and to find the terminating new-line character.

3

EXAMPLE

"a//b" //

four-character string literal

#include "//e"

//

undefined behavior

// */

//

comment, not syntax error

f = g/**//h; //

equivalent to

f = g / h;

//\

i(); //

part of a two-line comment

/\

/ j(); //

part of a two-line comment

#define glue(x,y) x##y

glue(/,/) k();

//

syntax error, not comment

/*//*/ l();

//

equivalent to

l();

m = n//**/o

+ p;

//

equivalent to

m = n + p;

71) Thus,

/*

...

*/

comments do not nest.

66 Language

§6.4.9

6.5 Expressions

1

An expression is a sequence of operators and operands that specifies computation of a
value, or that designates an object or a function, or that generates side effects, or that
performs a combination thereof.

2

Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression.

72)

Furthermore, the prior value

shall be read only to determine the value to be stored.

73)

3

The grouping of operators and operands is indicated by the syntax.

74)

Except as specified

later (for the function-call

()

,

&&

,

||

,

?:

, and comma operators), the order of evaluation

of subexpressions and the order in which side effects take place are both unspecified.

4

Some operators (the unary operator

~

, and the binary operators

<<

,

>>

,

&

,

^

, and

|

,

collectively described as bitwise operators) are required to have operands that have
integer type. These operators yield values that depend on the internal representations of
integers, and have implementation-defined and undefined aspects for signed types.

5

If an exceptional condition occurs during the evaluation of an expression (that is, if the
result is not mathematically defined or not in the range of representable values for its
type), the behavior is undefined.

6

The effective type of an object for an access to its stored value is the declared type of the
object, if any.

75)

If a value is stored into an object having no declared type through an

lvalue having a type that is not a character type, then the type of the lvalue becomes the

72) A floating-point status flag is not an object and can be set more than once within an expression.

73) This paragraph renders undefined statement expressions such as

i = ++i + 1;

a[i++] = i;

while allowing

i = i + 1;

a[i] = i;

74) The syntax specifies the precedence of operators in the evaluation of an expression, which is the same

as the order of the major subclauses of this subclause, highest precedence first. Thus, for example, the
expressions allowed as the operands of the binary

+

operator (6.5.6) are those expressions defined in

6.5.1 through 6.5.6. The exceptions are cast expressions (6.5.4) as operands of unary operators
(6.5.3), and an operand contained between any of the following pairs of operators: grouping
parentheses

()

(6.5.1), subscripting brackets

[]

(6.5.2.1), function-call parentheses

()

(6.5.2.2), and

the conditional operator

?:

(6.5.15).

Within each major subclause, the operators have the same precedence. Left- or right-associativity is
indicated in each subclause by the syntax for the expressions discussed therein.

75) Allocated objects have no declared type.

§6.5 Language

67

effective type of the object for that access and for subsequent accesses that do not modify
the stored value. If a value is copied into an object having no declared type using

memcpy

or

memmove

, or is copied as an array of character type, then the effective type

of the modified object for that access and for subsequent accesses that do not modify the
value is the effective type of the object from which the value is copied, if it has one. For
all other accesses to an object having no declared type, the effective type of the object is
simply the type of the lvalue used for the access.

7

An object shall have its stored value accessed only by an lvalue expression that has one of
the following types:

76)

— a type compatible with the effective type of the object,

— a qualified version of a type compatible with the effective type of the object,

— a type that is the signed or unsigned type corresponding to the effective type of the

object,

— a type that is the signed or unsigned type corresponding to a qualified version of the

effective type of the object,

— an aggregate or union type that includes one of the aforementioned types among its

members (including, recursively, a member of a subaggregate or contained union), or

— a character type.

8

A floating expression may be contracted, that is, evaluated as though it were an atomic
operation, thereby omitting rounding errors implied by the source code and the
expression evaluation method.

77)

The

FP_CONTRACT

pragma in

<math.h>

provides a

way to disallow contracted expressions. Otherwise, whether and how expressions are
contracted is implementation-defined.

78)

Forward references: the

FP_CONTRACT

pragma (7.12.2), copying functions (7.21.2).

76) The intent of this list is to specify those circumstances in which an object may or may not be aliased.

77) A contracted expression might also omit the raising of floating-point exceptions.

78) This license is specifically intended to allow implementations to exploit fast machine instructions that

combine multiple C operators. As contractions potentially undermine predictability, and can even
decrease accuracy for containing expressions, their use needs to be well-defined and clearly
documented.

68 Language

§6.5

6.5.1 Primary expressions

Syntax

1

primary-expression:

identifier
constant
string-literal

(

expression

)

Semantics

2

An identifier is a primary expression, provided it has been declared as designating an
object (in which case it is an lvalue) or a function (in which case it is a function
designator).

79)

3

A constant is a primary expression. Its type depends on its form and value, as detailed in
6.4.4.

4

A string literal is a primary expression. It is an lvalue with type as detailed in 6.4.5.

5

A parenthesized expression is a primary expression. Its type and value are identical to
those of the unparenthesized expression. It is an lvalue, a function designator, or a void
expression if the unparenthesized expression is, respectively, an lvalue, a function
designator, or a void expression.

Forward references: declarations (6.7).

6.5.2 Postfix operators

Syntax

1

postfix-expression:

primary-expression
postfix-expression

[

expression

]

postfix-expression

(

argument-expression-list

opt

)

postfix-expression

.

identifier

postfix-expression

->

identifier

postfix-expression

++

postfix-expression

--

(

type-name

) {

initializer-list

}

(

type-name

) {

initializer-list

, }

79) Thus, an undeclared identifier is a violation of the syntax.

§6.5.2 Language

69

argument-expression-list:

assignment-expression
argument-expression-list

,

assignment-expression

6.5.2.1 Array subscripting

Constraints

1

One of the expressions shall have type ‘‘pointer to object type’’, the other expression shall
have integer type, and the result has type ‘‘type’’.

Semantics

2

A postfix expression followed by an expression in square brackets

[]

is a subscripted

designation of an element of an array object. The definition of the subscript operator

[]

is that

E1[E2]

is identical to

(*((E1)+(E2)))

. Because of the conversion rules that

apply to the binary

+

operator, if

E1

is an array object (equivalently, a pointer to the

initial element of an array object) and

E2

is an integer,

E1[E2]

designates the

E2

-th

element of

E1

(counting from zero).

3

Successive subscript operators designate an element of a multidimensional array object.
If

E

is an n-dimensional array (n

2) with dimensions i

×

j

×

. . .

×

k, then

E

(used as

other than an lvalue) is converted to a pointer to an (n

1)-dimensional array with

dimensions j

×

. . .

×

k. If the unary

*

operator is applied to this pointer explicitly, or

implicitly as a result of subscripting, the result is the pointed-to (n

1)-dimensional array,

which itself is converted into a pointer if used as other than an lvalue. It follows from this
that arrays are stored in row-major order (last subscript varies fastest).

4

EXAMPLE Consider the array object defined by the declaration

int x[3][5];

Here

x

is a 3

×

5 array of

int

s; more precisely,

x

is an array of three element objects, each of which is an

array of five

int

s. In the expression

x[i]

, which is equivalent to

(*((x)+(i)))

,

x

is first converted to

a pointer to the initial array of five

int

s. Then

i

is adjusted according to the type of

x

, which conceptually

entails multiplying

i

by the size of the object to which the pointer points, namely an array of five

int

objects. The results are added and indirection is applied to yield an array of five

int

s. When used in the

expression

x[i][j]

, that array is in turn converted to a pointer to the first of the

int

s, so

x[i][j]

yields an

int

.

Forward references: additive operators (6.5.6), address and indirection operators
(6.5.3.2), array declarators (6.7.5.2).

70 Language

§6.5.2.1

6.5.2.2 Function calls

Constraints

1

The expression that denotes the called function

80)

shall have type pointer to function

returning

void

or returning an object type other than an array type.

2

If the expression that denotes the called function has a type that includes a prototype, the
number of arguments shall agree with the number of parameters. Each argument shall
have a type such that its value may be assigned to an object with the unqualified version
of the type of its corresponding parameter.

Semantics

3

A postfix expression followed by parentheses

()

containing a possibly empty, comma-

separated list of expressions is a function call. The postfix expression denotes the called
function. The list of expressions specifies the arguments to the function.

4

An argument may be an expression of any object type. In preparing for the call to a
function, the arguments are evaluated, and each parameter is assigned the value of the
corresponding argument.

81)

5

If the expression that denotes the called function has type pointer to function returning an
object type, the function call expression has the same type as that object type, and has the
value determined as specified in 6.8.6.4. Otherwise, the function call has type

void

. If

an attempt is made to modify the result of a function call or to access it after the next
sequence point, the behavior is undefined.

6

If the expression that denotes the called function has a type that does not include a
prototype, the integer promotions are performed on each argument, and arguments that
have type

float

are promoted to

double

. These are called the default argument

promotions. If the number of arguments does not equal the number of parameters, the
behavior is undefined. If the function is defined with a type that includes a prototype, and
either the prototype ends with an ellipsis (

, ...

) or the types of the arguments after

promotion are not compatible with the types of the parameters, the behavior is undefined.
If the function is defined with a type that does not include a prototype, and the types of
the arguments after promotion are not compatible with those of the parameters after
promotion, the behavior is undefined, except for the following cases:

80) Most often, this is the result of converting an identifier that is a function designator.

81) A function may change the values of its parameters, but these changes cannot affect the values of the

arguments. On the other hand, it is possible to pass a pointer to an object, and the function may
change the value of the object pointed to. A parameter declared to have array or function type is
adjusted to have a pointer type as described in 6.9.1.

§6.5.2.2 Language

71

— one promoted type is a signed integer type, the other promoted type is the

corresponding unsigned integer type, and the value is representable in both types;

— both types are pointers to qualified or unqualified versions of a character type or

void

.

7

If the expression that denotes the called function has a type that does include a prototype,
the arguments are implicitly converted, as if by assignment, to the types of the
corresponding parameters, taking the type of each parameter to be the unqualified version
of its declared type. The ellipsis notation in a function prototype declarator causes
argument type conversion to stop after the last declared parameter. The default argument
promotions are performed on trailing arguments.

8

No other conversions are performed implicitly; in particular, the number and types of
arguments are not compared with those of the parameters in a function definition that
does not include a function prototype declarator.

9

If the function is defined with a type that is not compatible with the type (of the
expression) pointed to by the expression that denotes the called function, the behavior is
undefined.

10

The order of evaluation of the function designator, the actual arguments, and
subexpressions within the actual arguments is unspecified, but there is a sequence point
before the actual call.

11

Recursive function calls shall be permitted, both directly and indirectly through any chain
of other functions.

12

EXAMPLE In the function call

(*pf[f1()]) (f2(), f3() + f4())

the functions

f1

,

f2

,

f3

, and

f4

may be called in any order. All side effects have to be completed before

the function pointed to by

pf[f1()]

is called.

Forward references: function declarators (including prototypes) (6.7.5.3), function
definitions (6.9.1), the

return

statement (6.8.6.4), simple assignment (6.5.16.1).

6.5.2.3 Structure and union members

Constraints

1

The first operand of the

.

operator shall have a qualified or unqualified structure or union

type, and the second operand shall name a member of that type.

2

The first operand of the

->

operator shall have type ‘‘pointer to qualified or unqualified

structure’’ or ‘‘pointer to qualified or unqualified union’’, and the second operand shall
name a member of the type pointed to.

72 Language

§6.5.2.3

Semantics

3

A postfix expression followed by the

.

operator and an identifier designates a member of

a structure or union object. The value is that of the named member,

82)

and is an lvalue if

the first expression is an lvalue. If the first expression has qualified type, the result has
the so-qualified version of the type of the designated member.

4

A postfix expression followed by the

->

operator and an identifier designates a member

of a structure or union object. The value is that of the named member of the object to
which the first expression points, and is an lvalue.

83)

If the first expression is a pointer to

a qualified type, the result has the so-qualified version of the type of the designated
member.

5

One special guarantee is made in order to simplify the use of unions: if a union contains
several structures that share a common initial sequence (see below), and if the union
object currently contains one of these structures, it is permitted to inspect the common
initial part of any of them anywhere that a declaration of the complete type of the union is
visible. Two structures share a common initial sequence if corresponding members have
compatible types (and, for bit-fields, the same widths) for a sequence of one or more
initial members.

6

EXAMPLE 1

If

f

is a function returning a structure or union, and

x

is a member of that structure or

union,

f().x

is a valid postfix expression but is not an lvalue.

7

EXAMPLE 2

In:

struct s { int i; const int ci; };

struct s s;

const struct s cs;

volatile struct s vs;

the various members have the types:

s.i int

s.ci const int

cs.i const int

cs.ci const int

vs.i volatile int

vs.ci volatile const int

82) If the member used to access the contents of a union object is not the same as the member last used to

store a value in the object, the appropriate part of the object representation of the value is reinterpreted
as an object representation in the new type as described in 6.2.6 (a process sometimes called "type
punning"). This might be a trap representation.

83) If

&E

is a valid pointer expression (where

&

is the ‘‘address-of ’’ operator, which generates a pointer to

its operand), the expression

(&E)->MOS

is the same as

E.MOS

.

§6.5.2.3 Language

73

8

EXAMPLE 3

The following is a valid fragment:

union {

struct {

int alltypes;

} n;

struct {

int type;

int intnode;

} ni;

struct {

int type;

double doublenode;

} nf;

} u;

u.nf.type = 1;

u.nf.doublenode = 3.14;

/*

...

*/

if (u.n.alltypes == 1)

if (sin(u.nf.doublenode) == 0.0)

/*

...

*/

The following is not a valid fragment (because the union type is not visible within function

f

):

struct t1 { int m; };

struct t2 { int m; };

int f(struct t1 *p1, struct t2 *p2)

{

if (p1->m < 0)

p2->m = -p2->m;

return p1->m;

}

int g()

{

union {

struct t1 s1;

struct t2 s2;

} u;

/*

...

*/

return f(&u.s1, &u.s2);

}

Forward references: address and indirection operators (6.5.3.2), structure and union
specifiers (6.7.2.1).

74 Language

§6.5.2.3

6.5.2.4 Postfix increment and decrement operators

Constraints

1

The operand of the postfix increment or decrement operator shall have qualified or
unqualified real or pointer type and shall be a modifiable lvalue.

Semantics

2

The result of the postfix

++

operator is the value of the operand. After the result is

obtained, the value of the operand is incremented. (That is, the value 1 of the appropriate
type is added to it.) See the discussions of additive operators and compound assignment
for information on constraints, types, and conversions and the effects of operations on
pointers. The side effect of updating the stored value of the operand shall occur between
the previous and the next sequence point.

3

The postfix

--

operator is analogous to the postfix

++

operator, except that the value of

the operand is decremented (that is, the value 1 of the appropriate type is subtracted from
it).

Forward references: additive operators (6.5.6), compound assignment (6.5.16.2).

6.5.2.5 Compound literals

Constraints

1

The type name shall specify an object type or an array of unknown size, but not a variable
length array type.

2

No initializer shall attempt to provide a value for an object not contained within the entire
unnamed object specified by the compound literal.

3

If the compound literal occurs outside the body of a function, the initializer list shall
consist of constant expressions.

Semantics

4

A postfix expression that consists of a parenthesized type name followed by a brace-
enclosed list of initializers is a compound literal. It provides an unnamed object whose
value is given by the initializer list.

84)

5

If the type name specifies an array of unknown size, the size is determined by the
initializer list as specified in 6.7.8, and the type of the compound literal is that of the
completed array type. Otherwise (when the type name specifies an object type), the type
of the compound literal is that specified by the type name. In either case, the result is an
lvalue.

84) Note that this differs from a cast expression. For example, a cast specifies a conversion to scalar types

or

void

only, and the result of a cast expression is not an lvalue.

§6.5.2.5 Language

75

6

The value of the compound literal is that of an unnamed object initialized by the
initializer list. If the compound literal occurs outside the body of a function, the object
has static storage duration; otherwise, it has automatic storage duration associated with
the enclosing block.

7

All the semantic rules and constraints for initializer lists in 6.7.8 are applicable to
compound literals.

85)

8

String literals, and compound literals with const-qualified types, need not designate
distinct objects.

86)

9

EXAMPLE 1

The file scope definition

int *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 the

second, four. The expressions in this compound literal are required to be constant. The unnamed object
has static storage duration.

10

EXAMPLE 2

In contrast, in

void 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 previously

pointed to by

p

and the second, zero. The expressions in this compound literal need not be constant. The

unnamed object has automatic storage duration.

11

EXAMPLE 3

Initializers with designations can be combined with compound literals. Structure objects

created 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});

12

EXAMPLE 4

A 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 with

the same or overlapping representations.

76 Language

§6.5.2.5

13

EXAMPLE 5

The 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 last

two hav e automatic storage duration when they occur within the body of a function, and the first of these
two is modifiable.

14

EXAMPLE 6

Like string literals, const-qualified compound literals can be placed into read-only memory

and can even be shared. For example,

(const char []){"abc"} == "abc"

might yield 1 if the literals’ storage is shared.

15

EXAMPLE 7

Since compound literals are unnamed, a single compound literal cannot specify a circularly

linked object. For example, there is no way to write a self-referential compound literal that could be used
as 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);

16

EXAMPLE 8

Each 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.

17

Note that if an iteration statement were used instead of an explicit

goto

and a labeled statement, the

lifetime of the unnamed object would be the body of the loop only, and on entry next time around

p

would

have an indeterminate value, which would result in undefined behavior.

Forward references: type names (6.7.6), initialization (6.7.8).

§6.5.2.5 Language

77

6.5.3 Unary operators

Syntax

1

unary-expression:

postfix-expression

++

unary-expression

--

unary-expression

unary-operator cast-expression

sizeof

unary-expression

sizeof (

type-name

)

unary-operator: one of

&

*

+

-

~

!

6.5.3.1 Prefix increment and decrement operators

Constraints

1

The operand of the prefix increment or decrement operator shall have qualified or
unqualified real or pointer type and shall be a modifiable lvalue.

Semantics

2

The value of the operand of the prefix

++

operator is incremented. The result is the new

value of the operand after incrementation. The expression

++E

is equivalent to

(E+=1)

.

See the discussions of additive operators and compound assignment for information on
constraints, types, side effects, and conversions and the effects of operations on pointers.

3

The prefix

--

operator is analogous to the prefix

++

operator, except that the value of the

operand is decremented.

Forward references: additive operators (6.5.6), compound assignment (6.5.16.2).

6.5.3.2 Address and indirection operators

Constraints

1

The 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 is

not declared with the

register

storage-class specifier.

2

The operand of the unary

*

operator shall have pointer type.

Semantics

3

The 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 were

omitted, except that the constraints on the operators still apply and the result is not an
lvalue. Similarly, if the operand is the result of a

[]

operator, neither the

&

operator nor

78 Language

§6.5.3.2

the unary

*

that is implied by the

[]

is evaluated and the result is as if the

&

operator

were removed and the

[]

operator were changed to a

+

operator. Otherwise, the result is

a pointer to the object or function designated by its operand.

4

The unary

*

operator denotes indirection. If the operand points to a function, the result is

a function designator; if it points to an object, the result is an lvalue designating the
object. If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an
invalid value has been assigned to the pointer, the behavior of the unary

*

operator is

undefined.

87)

Forward references: storage-class specifiers (6.7.1), structure and union specifiers
(6.7.2.1).

6.5.3.3 Unary arithmetic operators

Constraints

1

The operand of the unary

+

or

-

operator shall have arithmetic type; of the

~

operator,

integer type; of the

!

operator, scalar type.

Semantics

2

The result of the unary

+

operator is the value of its (promoted) operand. The integer

promotions are performed on the operand, and the result has the promoted type.

3

The result of the unary

-

operator is the negative of its (promoted) operand. The integer

promotions are performed on the operand, and the result has the promoted type.

4

The 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 is
not set). The integer promotions are performed on the operand, and the result has the
promoted type. If the promoted type is an unsigned type, the expression

~E

is equivalent

to the maximum value representable in that type minus

E

.

5

The result of the logical negation operator

!

is 0 if the value of its operand compares

unequal 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 is

always 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 of

an 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, an

address inappropriately aligned for the type of object pointed to, and the address of an object after the
end of its lifetime.

§6.5.3.3 Language

79

6.5.3.4 The

sizeof

operator

Constraints

1

The

sizeof

operator shall not be applied to an expression that has function type or an

incomplete type, to the parenthesized name of such a type, or to an expression that
designates a bit-field member.

Semantics

2

The

sizeof

operator yields the size (in bytes) of its operand, which may be an

expression or the parenthesized name of a type. The size is determined from the type of
the operand. The result is an integer. If the type of the operand is a variable length array
type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an
integer constant.

3

When 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 array
type, the result is the total number of bytes in the array.

88)

When applied to an operand

that has structure or union type, the result is the total number of bytes in such an object,
including internal and trailing padding.

4

The value of the result is implementation-defined, and its type (an unsigned integer type)
is

size_t

, defined in

<stddef.h>

(and other headers).

5

EXAMPLE 1

A principal use of the

sizeof

operator is in communication with routines such as storage

allocators and I/O systems. A storage-allocation function might accept a size (in bytes) of an object to
allocate 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 for

conversion to a pointer to

double

.

6

EXAMPLE 2

Another use of the

sizeof

operator is to compute the number of elements in an array:

sizeof array / sizeof array[0]

7

EXAMPLE 3

In this example, the size of a variable length array is computed and returned from a

function:

#include <stddef.h>

size_t fsize3(int n)

{

char b[n+3];

//

variable length array

return sizeof b;

//

execution time

sizeof

}

88) When applied to a parameter declared to have array or function type, the

sizeof

operator yields the

size of the adjusted (pointer) type (see 6.9.1).

80 Language

§6.5.3.4

int main()

{

size_t size;

size = fsize3(10); // fsize3

returns 13

return 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 operators

Syntax

1

cast-expression:

unary-expression

(

type-name

)

cast-expression

Constraints

2

Unless the type name specifies a void type, the type name shall specify qualified or
unqualified scalar type and the operand shall have scalar type.

3

Conversions that involve pointers, other than where permitted by the constraints of
6.5.16.1, shall be specified by means of an explicit cast.

Semantics

4

Preceding an expression by a parenthesized type name converts the value of the
expression to the named type. This construction is called a cast.

89)

A cast that specifies

no conversion has no effect on the type or value of an expression.

5

If the value of the expression is represented with greater precision or range than required
by the type named by the cast (6.3.1.8), then the cast specifies a conversion even if the
type of the expression is the same as the named type.

Forward references:

equality operators (6.5.9), function declarators (including

prototypes) (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 the

unqualified version of the type.

§6.5.4 Language

81

6.5.5 Multiplicative operators

Syntax

1

multiplicative-expression:

cast-expression
multiplicative-expression

*

cast-expression

multiplicative-expression

/

cast-expression

multiplicative-expression

%

cast-expression

Constraints

2

Each of the operands shall have arithmetic type. The operands of the

%

operator shall

have integer type.

Semantics

3

The usual arithmetic conversions are performed on the operands.

4

The result of the binary

*

operator is the product of the operands.

5

The result of the

/

operator is the quotient from the division of the first operand by the

second; the result of the

%

operator is the remainder. In both operations, if the value of

the second operand is zero, the behavior is undefined.

6

When integers are divided, the result of the

/

operator is the algebraic quotient with any

fractional part discarded.

90)

If the quotient

a/b

is representable, the expression

(a/b)*b + a%b

shall equal

a

.

6.5.6 Additive operators

Syntax

1

additive-expression:

multiplicative-expression
additive-expression

+

multiplicative-expression

additive-expression

-

multiplicative-expression

Constraints

2

For addition, either both operands shall have arithmetic type, or one operand shall be a
pointer to an object type and the other shall have integer type. (Incrementing is
equivalent to adding 1.)

3

For subtraction, one of the following shall hold:

— both operands have arithmetic type;

90) This is often called ‘‘truncation toward zero’’.

82 Language

§6.5.6

— both operands are pointers to qualified or unqualified versions of compatible object

types; or

— the left operand is a pointer to an object type and the right operand has integer type.

(Decrementing is equivalent to subtracting 1.)

Semantics

4

If both operands have arithmetic type, the usual arithmetic conversions are performed on
them.

5

The result of the binary

+

operator is the sum of the operands.

6

The result of the binary

-

operator is the difference resulting from the subtraction of the

second operand from the first.

7

For the purposes of these operators, a pointer to an object that is not an element of an
array behaves the same as a pointer to the first element of an array of length one with the
type of the object as its element type.

8

When an expression that has integer type is added to or subtracted from a pointer, the
result has the type of the pointer operand. If the pointer operand points to an element of
an array object, and the array is large enough, the result points to an element offset from
the original element such that the difference of the subscripts of the resulting and original
array elements equals the integer expression. In other words, if the expression

P

points to

the i-th element of an array object, the expressions

(P)+N

(equivalently,

N+(P)

) and

(P)-N

(where

N

has the value n) point to, respectively, the i+n-th and i−n-th elements of

the array object, provided they exist. Moreover, if the expression

P

points to the last

element of an array object, the expression

(P)+1

points one past the last element of the

array object, and if the expression

Q

points one past the last element of an array object,

the expression

(Q)-1

points to the last element of the array object. If both the pointer

operand and the result point to elements of the same array object, or one past the last
element of the array object, the evaluation shall not produce an overflow; otherwise, the
behavior is undefined. If the result points one past the last element of the array object, it
shall not be used as the operand of a unary

*

operator that is evaluated.

9

When two pointers are subtracted, both shall point to elements of the same array object,
or one past the last element of the array object; the result is the difference of the
subscripts of the two array elements. The size of the result is implementation-defined,
and its type (a signed integer type) is

ptrdiff_t

defined in the

<stddef.h>

header.

If the result is not representable in an object of that type, the behavior is undefined. In
other words, if the expressions

P

and

Q

point to, respectively, the i-th and j-th elements of

an array object, the expression

(P)-(Q)

has the value i−j provided the value fits in an

object of type

ptrdiff_t

. Moreover, if the expression

P

points either to an element of

an array object or one past the last element of an array object, and the expression

Q

points

to the last element of the same array object, the expression

((Q)+1)-(P)

has the same

§6.5.6 Language

83

value as

((Q)-(P))+1

and as

-((P)-((Q)+1))

, and has the value zero if the

expression

P

points one past the last element of the array object, even though the

expression

(Q)+1

does not point to an element of the array object.

91)

10

EXAMPLE Pointer arithmetic is well defined with pointers to variable length array types.

{

int n = 4, m = 3;

int a[n][m];

int (*p)[m] = a;

// p == &a[0]

p += 1;

// p == &a[1]

(*p)[2] = 99;

// a[1][2] == 99

n = p - a;

// n == 1

}

11

If array

a

in the above example were declared to be an array of known constant size, and pointer

p

were

declared to be a pointer to an array of the same known constant size (pointing to

a

), the results would be

the same.

Forward references: array declarators (6.7.5.2), common definitions

<stddef.h>

(7.17).

6.5.7 Bitwise shift operators

Syntax

1

shift-expression:

additive-expression
shift-expression

<<

additive-expression

shift-expression

>>

additive-expression

Constraints

2

Each of the operands shall have integer type.

Semantics

3

The integer promotions are performed on each of the operands. The type of the result is
that of the promoted left operand. If the value of the right operand is negative or is
greater than or equal to the width of the promoted left operand, the behavior is undefined.

91) Another way to approach pointer arithmetic is first to convert the pointer(s) to character pointer(s): In

this scheme the integer expression added to or subtracted from the converted pointer is first multiplied
by the size of the object originally pointed to, and the resulting pointer is converted back to the
original type. For pointer subtraction, the result of the difference between the character pointers is
similarly divided by the size of the object originally pointed to.

When viewed in this way, an implementation need only provide one extra byte (which may overlap
another object in the program) just after the end of the object in order to satisfy the ‘‘one past the last
element’’ requirements.

84 Language

§6.5.7

4

The result of

E1 << E2

is

E1

left-shifted

E2

bit positions; vacated bits are filled with

zeros. If

E1

has an unsigned type, the value of the result is

E1

×

2

E2

, reduced modulo

one more than the maximum value representable in the result type. If

E1

has a signed

type and nonnegative value, and

E1

×

2

E2

is representable in the result type, then that is

the resulting value; otherwise, the behavior is undefined.

5

The result of

E1 >> E2

is

E1

right-shifted

E2

bit positions. If

E1

has an unsigned type

or if

E1

has a signed type and a nonnegative value, the value of the result is the integral

part of the quotient of

E1

/ 2

E2

. If

E1

has a signed type and a negative value, the

resulting value is implementation-defined.

6.5.8 Relational operators

Syntax

1

relational-expression:

shift-expression
relational-expression

<

shift-expression

relational-expression

>

shift-expression

relational-expression

<=

shift-expression

relational-expression

>=

shift-expression

Constraints

2

One of the following shall hold:

— both operands have real type;

— both operands are pointers to qualified or unqualified versions of compatible object

types; or

— both operands are pointers to qualified or unqualified versions of compatible

incomplete types.

Semantics

3

If both of the operands have arithmetic type, the usual arithmetic conversions are
performed.

4

For the purposes of these operators, a pointer to an object that is not an element of an
array behaves the same as a pointer to the first element of an array of length one with the
type of the object as its element type.

5

When two pointers are compared, the result depends on the relative locations in the
address space of the objects pointed to. If two pointers to object or incomplete types both
point to the same object, or both point one past the last element of the same array object,
they compare equal. If the objects pointed to are members of the same aggregate object,
pointers to structure members declared later compare greater than pointers to members
declared earlier in the structure, and pointers to array elements with larger subscript

§6.5.8 Language

85

values compare greater than pointers to elements of the same array with lower subscript
values. All pointers to members of the same union object compare equal. If the
expression

P

points to an element of an array object and the expression

Q

points to the

last element of the same array object, the pointer expression

Q+1

compares greater than

P

. In all other cases, the behavior is undefined.

6

Each of the operators

<

(less than),

>

(greater than),

<=

(less than or equal to), and

>=

(greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.

92)

The result has type

int

.

6.5.9 Equality operators

Syntax

1

equality-expression:

relational-expression
equality-expression

==

relational-expression

equality-expression

!=

relational-expression

Constraints

2

One of the following shall hold:

— both operands have arithmetic type;

— both operands are pointers to qualified or unqualified versions of compatible types;

— one operand is a pointer to an object or incomplete type and the other is a pointer to a

qualified or unqualified version of

void

; or

— one operand is a pointer and the other is a null pointer constant.

Semantics

3

The

==

(equal to) and

!=

(not equal to) operators are analogous to the relational

operators except for their lower precedence.

93)

Each of the operators yields 1 if the

specified relation is true and 0 if it is false. The result has type

int

. For any pair of

operands, exactly one of the relations is true.

4

If both of the operands have arithmetic type, the usual arithmetic conversions are
performed. Values of complex types are equal if and only if both their real parts are equal
and also their imaginary parts are equal. Any two values of arithmetic types from
different type domains are equal if and only if the results of their conversions to the
(complex) result type determined by the usual arithmetic conversions are equal.

92) The expression

a<b<c

is not interpreted as in ordinary mathematics. As the syntax indicates, it

means

(a<b)<c

; in other words, ‘‘if

a

is less than

b

, compare 1 to

c

; otherwise, compare 0 to

c

’’.

93) Because of the precedences,

a<b == c<d

is 1 whenever

a<b

and

c<d

have the same truth-value.

86 Language

§6.5.9

5

Otherwise, at least one operand is a pointer. If one operand is a pointer and the other is a
null pointer constant, the null pointer constant is converted to the type of the pointer. If
one operand is a pointer to an object or incomplete type and the other is a pointer to a
qualified or unqualified version of

void

, the former is converted to the type of the latter.

6

Tw o pointers compare equal if and only if both are null pointers, both are pointers to the
same object (including a pointer to an object and a subobject at its beginning) or function,
both are pointers to one past the last element of the same array object, or one is a pointer
to one past the end of one array object and the other is a pointer to the start of a different
array object that happens to immediately follow the first array object in the address
space.

94)

7

For the purposes of these operators, a pointer to an object that is not an element of an
array behaves the same as a pointer to the first element of an array of length one with the
type of the object as its element type.

6.5.10 Bitwise

AND

operator

Syntax

1

AND-expression:

equality-expression
AND-expression

&

equality-expression

Constraints

2

Each of the operands shall have integer type.

Semantics

3

The usual arithmetic conversions are performed on the operands.

4

The result of the binary

&

operator is the bitwise

AND

of the operands (that is, each bit in

the result is set if and only if each of the corresponding bits in the converted operands is
set).

94) Tw o objects may be adjacent in memory because they are adjacent elements of a larger array or

adjacent members of a structure with no padding between them, or because the implementation chose
to place them so, even though they are unrelated. If prior invalid pointer operations (such as accesses
outside array bounds) produced undefined behavior, subsequent comparisons also produce undefined
behavior.

§6.5.10 Language

87

6.5.11 Bitwise exclusive

OR

operator

Syntax

1

exclusive-OR-expression:

AND-expression
exclusive-OR-expression

^

AND-expression

Constraints

2

Each of the operands shall have integer type.

Semantics

3

The usual arithmetic conversions are performed on the operands.

4

The result of the

^

operator is the bitwise exclusive

OR

of the operands (that is, each bit

in the result is set if and only if exactly one of the corresponding bits in the converted
operands is set).

6.5.12 Bitwise inclusive

OR

operator

Syntax

1

inclusive-OR-expression:

exclusive-OR-expression
inclusive-OR-expression

|

exclusive-OR-expression

Constraints

2

Each of the operands shall have integer type.

Semantics

3

The usual arithmetic conversions are performed on the operands.

4

The result of the

|

operator is the bitwise inclusive

OR

of the operands (that is, each bit in

the result is set if and only if at least one of the corresponding bits in the converted
operands is set).

88 Language

§6.5.12

6.5.13 Logical

AND

operator

Syntax

1

logical-AND-expression:

inclusive-OR-expression
logical-AND-expression

&&

inclusive-OR-expression

Constraints

2

Each of the operands shall have scalar type.

Semantics

3

The

&&

operator shall yield 1 if both of its operands compare unequal to 0; otherwise, it

yields 0. The result has type

int

.

4

Unlike the bitwise binary

&

operator, the

&&

operator guarantees left-to-right evaluation;

there is a sequence point after the evaluation of the first operand. If the first operand
compares equal to 0, the second operand is not evaluated.

6.5.14 Logical

OR

operator

Syntax

1

logical-OR-expression:

logical-AND-expression
logical-OR-expression

||

logical-AND-expression

Constraints

2

Each of the operands shall have scalar type.

Semantics

3

The

||

operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it

yields 0. The result has type

int

.

4

Unlike the bitwise

|

operator, the

||

operator guarantees left-to-right evaluation; there is

a sequence point after the evaluation of the first operand. If the first operand compares
unequal to 0, the second operand is not evaluated.

§6.5.14 Language

89

6.5.15 Conditional operator

Syntax

1

conditional-expression:

logical-OR-expression
logical-OR-expression

?

expression

:

conditional-expression

Constraints

2

The first operand shall have scalar type.

3

One of the following shall hold for the second and third operands:

— both operands have arithmetic type;

— both operands have the same structure or union type;

— both operands have void type;

— both operands are pointers to qualified or unqualified versions of compatible types;

— one operand is a pointer and the other is a null pointer constant; or

— one operand is a pointer to an object or incomplete type and the other is a pointer to a

qualified or unqualified version of

void

.

Semantics

4

The first operand is evaluated; there is a sequence point after its evaluation. The second
operand is evaluated only if the first compares unequal to 0; the third operand is evaluated
only if the first compares equal to 0; the result is the value of the second or third operand
(whichever is evaluated), converted to the type described below.

95)

If an attempt is made

to modify the result of a conditional operator or to access it after the next sequence point,
the behavior is undefined.

5

If both the second and third operands have arithmetic type, the result type that would be
determined by the usual arithmetic conversions, were they applied to those two operands,
is the type of the result. If both the operands have structure or union type, the result has
that type. If both operands have void type, the result has void type.

6

If both the second and third operands are pointers or one is a null pointer constant and the
other is a pointer, the result type is a pointer to a type qualified with all the type qualifiers
of the types pointed-to by both operands. Furthermore, if both operands are pointers to
compatible types or to differently qualified versions of compatible types, the result type is
a pointer to an appropriately qualified version of the composite type; if one operand is a
null pointer constant, the result has the type of the other operand; otherwise, one operand
is a pointer to

void

or a qualified version of

void

, in which case the result type is a

95) A conditional expression does not yield an lvalue.

90 Language

§6.5.15

pointer to an appropriately qualified version of

void

.

7

EXAMPLE The common type that results when the second and third operands are pointers is determined
in two independent stages. The appropriate qualifiers, for example, do not depend on whether the two
pointers have compatible types.

8

Given the declarations

const void *c_vp;

void *vp;

const int *c_ip;

volatile int *v_ip;

int *ip;

const char *c_cp;

the third column in the following table is the common type that is the result of a conditional expression in
which the first two columns are the second and third operands (in either order):

c_vp c_ip const void *

v_ip 0

volatile int *

c_ip v_ip const volatile int *

vp c_cp

const void *

ip c_ip

const int *

vp ip void *

6.5.16 Assignment operators

Syntax

1

assignment-expression:

conditional-expression
unary-expression assignment-operator assignment-expression

assignment-operator: one of

=

*=

/=

%=

+=

-=

<<= >>= &= ^= |=

Constraints

2

An assignment operator shall have a modifiable lvalue as its left operand.

Semantics

3

An assignment operator stores a value in the object designated by the left operand. An
assignment expression has the value of the left operand after the assignment, but is not an
lvalue. The type of an assignment expression is the type of the left operand unless the
left operand has qualified type, in which case it is the unqualified version of the type of
the left operand. The side effect of updating the stored value of the left operand shall
occur between the previous and the next sequence point.

4

The order of evaluation of the operands is unspecified. If an attempt is made to modify
the result of an assignment operator or to access it after the next sequence point, the
behavior is undefined.

§6.5.16 Language

91

6.5.16.1 Simple assignment

Constraints

1

One of the following shall hold:

96)

— the left operand has qualified or unqualified arithmetic type and the right has

arithmetic type;

— the left operand has a qualified or unqualified version of a structure or union type

compatible with the type of the right;

— both operands are pointers to qualified or unqualified versions of compatible types,

and the type pointed to by the left has all the qualifiers of the type pointed to by the
right;

— one operand is a pointer to an object or incomplete type and the other is a pointer to a

qualified or unqualified version of

void

, and the type pointed to by the left has all

the qualifiers of the type pointed to by the right;

— the left operand is a pointer and the right is a null pointer constant; or

— the left operand has type

_Bool

and the right is a pointer.

Semantics

2

In simple assignment (

=

), the value of the right operand is converted to the type of the

assignment expression and replaces the value stored in the object designated by the left
operand.

3

If the value being stored in an object is read from another object that overlaps in any way
the storage of the first object, then the overlap shall be exact and the two objects shall
have qualified or unqualified versions of a compatible type; otherwise, the behavior is
undefined.

4

EXAMPLE 1

In the program fragment

int f(void);

char c;

/*

...

*/

if ((c = f()) == -1)

/*

...

*/

the

int

value returned by the function may be truncated when stored in the

char

, and then converted back

to

int

width prior to the comparison. In an implementation in which ‘‘plain’’

char

has the same range of

values as

unsigned char

(and

char

is narrower than

int

), the result of the conversion cannot be

96) The asymmetric appearance of these constraints with respect to type qualifiers is due to the conversion

(specified in 6.3.2.1) that changes lvalues to ‘‘the value of the expression’’ and thus removes any type
qualifiers that were applied to the type category of the expression (for example, it removes

const

but

not

volatile

from the type

int volatile * const

).

92 Language

§6.5.16.1

 

 

 

 

 

 

 

Content      ..     3      4      5      6     ..