external appearance or action
unspecified behavior where each implementation documents how the choice is made
behavior that depends on local conventions of nationality, culture, and language that each implementation documents
behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements
use of an unspecified value, or other behavior where this International Standard provides two or more possibilities and imposes no further requirements on which is chosen in any instance
unit of data storage in the execution environment large enough to hold an object that may have one of two values
addressable unit of data storage large enough to hold any member of the basic character set of the execution environment
〈abstract〉 member of a set of elements used for the organization, control, or representation of data
single-byte character 〈C〉 bit representation that fits in a byte
sequence of one or more bytes representing a member of the extended character set of either the source or the execution environment
bit representation that fits in an object of type wchar_t, capable of representing any character in the current locale
region of data storage in the execution environment, the contents of which can represent values
precise meaning of the contents of an object when interpreted as having a specific type
The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant.
Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.
At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place.
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.
An object has a storage duration that determines its lifetime.
If an object is referred to outside of its lifetime, the behavior is undefined.
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.
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).
Any number of derived types can be constructed from the object, function, and incomplete types, as follows:
A pointer type may be derived from a function type, an object type, or an incomplete type, called the referenced type.
An lvalue is an expression with an object type or an incomplete type other than void;
The (nonexistent) value of a void expression (an expression that has type void) shall not be used in any way, and implicit or explicit conversions (except to void) shall not be applied to such an expression.
A pointer to void may be converted to or from a pointer to any incomplete or object type.
The value of a constant shall be in the range of representable values for its type.
The type of an integer constant is the first of the corresponding list in which its value can be represented.
An unsuffixed floating constant has type double.
An identifier declared as an enumeration constant has type int.
An integer character constant has type int.
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.
int i = '\xFF'; // 底層實現 (即編譯器) 預設為 signed char。 printf("sizeof: %d", i ); // 輸出 -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.
The left operand of a comma operator is evaluated as a void expression;
A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.
The declaration specifiers consist of a sequence of specifiers that indicate the linkage, storage duration, and part of the type of the entities that the declarators denote.
typedef struct MY_TYPE { boolean flag; short int value; double stuff; } MY_TYPE; void function(void) { MY_TYPE a = { .flag = true, .value = 123, .stuff = 0.456 }; ^^^^^ designator }
A statement specifies an action to be performed.
A block allows a set of declarations and statements to be grouped into one syntactic unit.
A selection statement selects among a set of statements depending on the value of a controlling expression.
There shall be no more than one external definition for each identifier declared with internal linkage in a translation unit.
function-definition: declaration-specifiers declarator declaration-listopt compound-statement ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^ void foo(int i) { ... }
If the declaration of an identifier for an object has file scope and an initializer, the declaration is an external definition for the identifier.
A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition.
int gFoo; // tentative definition static int gBAR; // tentative definition
unsigned char c1 = 255, c2 = 2; int n = c1 + c2; ^^ ^^ unsigned char unsigned char | | int int
If an int can represent all values of the original type, the value is converted to an int;
If both operands have the same type, then no further conversion is needed.
Otherwise, the integer promotions are performed on both operands.
Then the following rules are applied to the promoted operands:
If both operands have the same type, then no further conversion is needed.
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.
Every integer type has an integer conversion rank defined as follows:
No two signed integer types shall have the same rank, even if they have the same representation.
The rank of a signed integer type shall be greater than the rank of any signed integer type with less precision.
The rank of long long int shall be greater than the rank of long int, which shall be greater than the rank of int, which shall be greater than the rank of short int, which shall be greater than the rank of signed char.
The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, if any.
The rank of any standard integer type shall be greater than the rank of any extended integer type with the same width.
The rank of char shall equal the rank of signed char and unsigned char.
The rank of _Bool shall be less than the rank of all other standard integer types.
The rank of any enumerated type shall equal the rank of the compatible integer type (see 6.7.2.2).
For all integer types T1, T2, and T3, if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 has greater rank than T3.
If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int.These are called the integer promotions. All other types are unchanged by the integer promotions.
The integer promotions are applied only: as part of the usual arithmetic conversions, to certain argument expressions, to the operands of the unary +, -, and ~ operators, and to both operands of the shift operators, as specified by their respective subclauses.
When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.
Many operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to determine a common real type for the operands and result.
Otherwise, the integer promotions are performed on both operands.
If both operands have the same type, then no further conversion is needed.
Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank is converted to the type of the operand with greater rank.
Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.
Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.
Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
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.
-Wall
和 -Wextra
。unsigned int u = 1234; int i = -5678; unsigned int result = u + i; // i 會被轉換成 unsigned int,其值不再是負數。