C 和 C++ 中有哪些容易被坑的 undefined behaviour?

关注者
740
被浏览
54,421
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

ISO/IEC 9899 201X

J.2 Undefined behavior
1 The behavior is undefined in the following circumstances:
— A ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint is violated (clause 4).
— A nonempty source file does not end in a new-line character which is not immediately preceded by a backslash character or ends in a partial preprocessing token or comment (5.1.1.2).
— Token concatenation produces a character sequence matching the syntax of a universal character name (5.1.1.2).
— A program in a hosted environment does not define a function named main using one of the specified forms (5.1.2.2.1).
— The execution of a program contains a data race (5.1.2.4).
— A character not in the basic source character set is encountered in a source file, except in an identifier, a character constant, a string literal, a header name, a comment, or a preprocessing token that is never converted to a token (5.2.1).
— An identifier, comment, string literal, character constant, or header name contains an invalid multibyte character or does not begin and end in the initial shift state (5.2.1.2).
— The same identifier has both internal and external linkage in the same translation unit
(6.2.2).
— An object is referred to outside of its lifetime (6.2.4).
— The value of a pointer to an object whose lifetime has ended is used (6.2.4).
— The value of an object with automatic storage duration is used while it is indeterminate (6.2.4, 6.7.9, 6.8).
— A trap representation is read by an lvalue expression that does not have character type
(6.2.6.1).
— A trap representation is produced by a side effect that modifies any part of the object using an lvalue expression that does not have character type (6.2.6.1).
— The operands to certain operators are such that they could produce a negative zero result, but the implementation does not support negative zeros (6.2.6.2).
— Two declarations of the same object or function specify types that are not compatible
(6.2.7).
— A program requires the formation of a composite type from a variable length array type whose size is specified by an expression that is not evaluated (6.2.7).
— Conversion to or from an integer type produces a value outside the range that can be represented (6.3.1.4).
— Demotion of one real floating type to another produces a value outside the range that can be represented (6.3.1.5).
— An lvalue does not designate an object when evaluated (6.3.2.1).
— A non-array lvalue with an incomplete type is used in a context that requires the value of the designated object (6.3.2.1).
— An lvalue designating an object of automatic storage duration that could have been declared with the register storage class is used in a context that requires the value of the designated object, but the object is uninitialized. (6.3.2.1).
— An lvalue having array type is converted to a pointer to the initial element of the array, and the array object has register storage class (6.3.2.1).
— An attempt is made to use the value of a void expression, or an implicit or explicit conversion (except to void) is applied to a void expression (6.3.2.2).
— Conversion of a pointer to an integer type produces a value outside the range that can be represented (6.3.2.3).
— Conversion between two pointer types produces a result that is incorrectly aligned (6.3.2.3).
— A pointer is used to call a function whose type is not compatible with the referenced type (6.3.2.3).
— An unmatched ' or " character is encountered on a logical source line during tokenization (6.4).
— A reserved keyword token is used in translation phase 7 or 8 for some purpose other than as a keyword (6.4.1).
— A universal character name in an identifier does not designate a character whose encoding falls into one of the specified ranges (6.4.2.1).
— The initial character of an identifier is a universal character name designating a digit (6.4.2.1).
— Two identifiers differ only in nonsignificant characters (6.4.2.1).
— The identifier _ _func_ _ is explicitly declared (6.4.2.2).
— The program attempts to modify a string literal (6.4.5).
— The characters ', \, ", //, or /* occur in the sequence between the < and > delimiters, or the characters ', \, //, or /* occur in the sequence between the " delimiters, in a header name preprocessing token (6.4.7).
— A side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object (6.5).
— An exceptional condition occurs during the evaluation of an expression (6.5).
— An object has its stored value accessed other than by an lvalue of an allowable type (6.5).
— For a call to a function without a function prototype in scope, the number of arguments does not equal the number of parameters (6.5.2.2).
— For call to a function without a function prototype in scope where the function is defined with a function prototype, either the prototype ends with an ellipsis or the types of the arguments after promotion are not compatible with the types of the parameters (6.5.2.2).


......略(还有一堆没贴)


以上各种Undefine Behavior。至于容易被坑。。。讲道理你不知道的话都容易被坑。(不用等于无敌那当我没说。)其实不只是Undefine Behavior会坑人,implementation-defined behavior、locale-specific behavior、unspecified behavior很多时候都能坑的你吐血。