# The New C Standard- P16

Chia sẻ: Thanh Cong | Ngày: | Loại File: PDF | Số trang:112

0
53
lượt xem
4

## The New C Standard- P16

Mô tả tài liệu

Tham khảo tài liệu 'the new c standard- p16', công nghệ thông tin, kỹ thuật lập trình phục vụ nhu cầu học tập, nghiên cứu và làm việc hiệu quả

Chủ đề:

Bình luận(0)

Lưu

## Nội dung Text: The New C Standard- P16

1. 6.10.1 Conditional inclusion 1883 • The speciﬁcation has changed between C90 and C99. The problem with any guideline recommendation is that the total cost is likely to be greater than the total beneﬁt (a cost is likely to be incurred in many cases and a beneﬁt obtained in very few cases). For this reason 835 integer no recommendation is made here. The discussion on sufﬁxed integer constants is also applicable in the constant type ﬁrst in list context of a conditional inclusion directive. Example In the following the developer may assume that unwanted higher bits in the value of C will be truncated when shifted left. 1 #define C 0x1100u 2 #define INT_BITS 32 3 4 #define TOP_BYTE (C
2. 1888 6.10.1 Conditional inclusion Commentary basic char- 478 acter set The guarantee on the value being nonnegative does not apply during preprocessing. For instance, a pre- positive if stored in char object processing using the EBCDIC character set and acting as if the type char was signed. In other contexts character 885 the value of a character constant containing a single-character that is not a member of the basic execution constant character set is implementation-deﬁned. more than one character Coding Guidelines character 885 constant The discussion on the possibility of character constants having other implementation-deﬁned values is more than one character applicable here. #ifdef Preprocessing directives of the forms 1884 #ifndef # ifdef identifier new-line groupopt # ifndef identifier new-line groupopt check whether the identiﬁer is or is not currently deﬁned as a macro name. Commentary There is no #elifdef form (although over half of the uses of the #elif directive are followed by a single instance of the defined operator— Table 1872.1). Their conditions are equivalent to #if defined identifier and #if !defined identifier respectively. 1885 Commentary The #ifdef and #ifndef forms are rather like the unary ++ and -- operators in that they provide a short hand notation for commonly used functionality. Coding Guidelines The #ifdef forms are the most common form of conditional inclusion directive. Measurements (see Table 1872.1) also show that nearly a third of the uses of the defined operator could be replaced by one of these forms. There are advantages (e.g., most common form suggests most practiced form for readers, and ease of visual scanning down the left edge of the source) and disadvantages (e.g., requires more effort to add additional conditions to the single test being made) to using the #ifdef forms, instead of the defined operator. However, there does not appear to be a worthwhile cost/beneﬁt to recommending one of the possibilities. 142) Thus on an implementation where INT_MAX is 0x7FFF and UINT_MAX is 0xFFFF, the constant 0x8000 1886 is signed and positive within a #if expression even though it is unsigned in translation phase 7. Commentary The wording was changed by the response to DR #265. footnote 143) Thus, the constant expression in the following #if directive and if statement is not guaranteed to 1887 143 evaluate to the same value in these two contexts. #if ’z’ - ’a’ == 25 if (’z’ - ’a’ == 25) Commentary This situation could occur, for instance, if the Ascii representation were used during the preprocessing phases transla- 133 tion phase and EBCDIC were used during translation phase 5. 5 Each directive’s condition is checked in order. 1888 v 1.2 June 24, 2009
3. 6.10.1 Conditional inclusion 1890 Commentary The order is from the lowest line number to the highest line number. Coding Guidelines It may be possible to obtain some translation time performance advantage (at least for the original developer) 1739 selection by appropriately ordering the directives. Unlike developer behavior with if statements, developers do not statement syntax usually aim to optimize speed of translation when deciding how to order conditional inclusion directives (experience suggests that developers often simply append new directive to the end of any existing directives). Recognizing a known pattern in a sequence of directives has several beneﬁts for readers. They can make use of any previous deductions they have made on how to interpret the directives and what they represent, and the usage highlights common dependencies in the source. In the following code fragment more reader effort is required to spot similarities in the sequence that directives are checked than if both sequences of directives had occurred in the same order. 1 #ifdef MACHINE_A 2 /* ... */ 3 #else 4 #ifdef MACHINE_B 5 /* ... */ 6 #endif 7 #endif 8 9 #ifdef MACHINE_B 10 /* ... */ 11 #else 12 #ifdef MACHINE_A 13 /* ... */ 14 #endif 15 #endif Given the lack of attention from developers on the relative ordering of directives and the beneﬁts of using the same ordering, where possible, a guideline recommendation appears worthwhile. However, a guideline 0 guideline rec- recommendation needs to be automatically enforceable and determining when two sequences of directives ommendation enforceable have the same affect, during translation, may be infeasible because information that is not contained within the source may be required (e.g., dependencies between macro names that are likely to be deﬁned via translator command line options). Rev 1888.1 Where possible the visual order of evaluation of expressions within different sequences of nested conditional inclusion directives shall be the same. 1889 If it evaluates to false (zero), the group that it controls is skipped: directives are processed only through the name that determines the directive in order to keep track of the level of nested conditionals; Commentary 1744 if statement A parallel can be drawn with the behavior of if statements, in that if their controlling expression evaluates to operand compare against 0 zero, during program execution, any statements in the associated block are skipped. 1890 directives are processed only through the name that determines the directive in order to keep track of the level directive processing of nested conditionals; while skipping Commentary The preprocessor operates on a representation of the source written by the developer, not translated machine code. As such it needs to perform some processing on its input to be able to deduce when to stop skipping. June 24, 2009 v 1.2
4. 1891 6.10.1 Conditional inclusion × × #if part 1,000 × • #else part •× Translation units • ×× Top level ﬁles ×• •× × 100 × ×× •× • ×× ×× ×× ×× × • • × ×× • × × •× × •• ×× × ××× • • •• •• × × • × × ×× •× × × × ×× ×× × × × •• • × × × × • ×× × × × ××× × × × • × × × × ×× × × ××× × × ×× × × ×××××× × × × × × × 10 •• • • ×× • × ••• • • • ×× ××××××× × × ×• • × ××× × ×× × × × × ×× • × •× ×× × × × × ××× ×××× × ×× × × ×× × × •• • × × ×× × × • • • × × × ×××× × × × × × ×× × • × • •× × ×× × ×× ×× ×× × × • •• • •• •× × × × × × × ×× × × × ×× × • • × • ×• × × × × ××× • • × × × ×× × ×× 1 • •• •• • • • • ••• •• • ×× × ×× × × • ×× ××• × ×× × •• • ××× × × × × ×× × × × • ××× ×× •• ••• • • • • • × ×× × • × ×× × × × × ×× × × •× × 50 100 150 50 100 150 Physical lines skipped Physical lines skipped Figure 1889.1: Number of top-level source ﬁles (i.e., the contents of any included ﬁles are not counted) and (right) complete translation units (including the contents of any ﬁles #included more than once) having a given number of lines skipped during translation of this book’s benchmark programs. Directives need to be processed to keep track of the level of nesting of conditionals and translation phases transla- 116 tion phase 1–3 still need to be performed (line splicing could affect what is or is not the start of a line) and characters 1 within a comment must not be treated as directives. The intent of only requiring a minimum of directive processing, while skipping, is to enable partially written source code to be skipped and to allow preprocessors to optimize their performance in this special case, speeding up the rate at which the input is processed. Example 1 #if 1 2 extern int ei; 3 4 #elif " an unmatched quote character, undefined behavior 5 6 extern int foo_bar; 7 #endif 8 9 #if 0 10 printf("\ 11 #endif \n"); 12 13 #endif 14 15 #if 0 16 /* 17 #endif 18 */ 19 #endif the rest of the directives’ preprocessing tokens are ignored, as are the other preprocessing tokens in the 1891 group. Commentary preprocessor 1854 directives syntax There is no requirement that any directive be properly formed, according to the preprocessor syntax. However, transla- 124 tion phase preprocessing tokens still need to be created, before they are ignored (as part of translation phase 3). 3 v 1.2 June 24, 2009
5. 6.10.2 Source ﬁle inclusion 1896 Example In the following the #define directive is not well formed. But because this group is being skipped the translator is required to ignore this fact. 1 #if 0 2 #define M(e 3 #endif 1892 Only the ﬁrst group whose control condition evaluates to true (nonzero) is processed. Commentary This group is processed exactly as-if it appeared in the source outside of any group. 1893 If none of the conditions evaluates to true, and there is a #else directive, the group controlled by the #else is processed; Commentary A semantic rule to associate #else with the lexically nearest preceding #if (or similar form) directive, like 1747 else the one given for if statements, is not needed because conditional inclusion is terminated by a #endif binds to near- est if directive. Like the matching #if (or similar form) directive case, all preprocessing tokens in the group are treated as if they appeared outside of any conditional inclusion directive. Processing continues until the ﬁrst #endif is encountered (which must match the opening directive). Coding Guidelines The arguments made for if statements always containing an else arm might be thought to also apply to 1745 else conditional inclusion. However, the presence of a matching #endif directive reduces the likelihood that readers will confuse which preprocessing directive any #else associates with (although other issues, such as lack of indentation or a large number of source lines between directives can make it difﬁcult to visually associate matching directives). 1894 lacking a #else directive, all the groups until the #endif are skipped.144) Commentary 1747 else The affect of this speciﬁcation mimics the behavior of if statements. binds to near- est if 1895 Forward references: macro replacement (6.10.3), source ﬁle inclusion (6.10.2), largest integer types (7.18.1.5). 6.10.2 Source ﬁle inclusion Constraints 1896 A #include directive shall identify a header or source ﬁle that can be processed by the implementation. source ﬁle inclusion Commentary There is no requirement that a header be represented using a source ﬁle. It could be represented using prebuilt 2018 footnote 153 information within the translator that is enabled only when the appropriate #include directive is encountered during preprocessing (but not in a group that is skipped). Also there is no requirement that the spelling of the header in the C source ﬁle be represented by a source ﬁle of the same spelling. The C Standard has no explicit knowledge of ﬁle systems and is silent on the issue of directory structures. Minimum required limits 1909 #include on the implementation processing of a header name are speciﬁed elsewhere. mapping to host ﬁle Failure to locate a header or source ﬁle that can be processed by the implementation (e.g., a ﬁle of the speciﬁed name does not exist, at least along the places searched) is a constraint violation. June 24, 2009 v 1.2
7. 6.10.2 Source ﬁle inclusion 1897 × 1,000 × × Translation units × × 100 × × × × × × × × × 10 × × × × × × 1 0 5 10 15 20 Unnecessary headers #include’d Figure 1896.2: Number of preprocessing translation units (excluding system headers) containing a given number of #includes whose contents are not referenced during translation (excludes the case where the same header is #included more than once, see Figure 1896.1). Based on the translated form of this book’s benchmark programs. 1,000 Source ﬁles 100 10 "header" 1 0 10 20 30 40 50 60 #includes Figure 1896.3: Number of .c source ﬁles containing a given number of #include directives (dashed lines represent number of unique headers). Based on the visible form of the .c ﬁles. Experience suggests that once a #include directive appears in a source ﬁle it is rarely removed (see Figure 1896.2) and that new #include directives are simply added after the last one. The issue of redundant code is discussed elsewhere. 190 redundant code There does not appear to be a worthwhile beneﬁt in ordering #include directives in any way (apart from any relative ordering dictated by dependencies between headers). Table 1896.1: Occurrence of two forms of header-names (as a percentage of all #include directives), the percentage of each kind that speciﬁes a path to the header ﬁle, and number of absolute paths speciﬁed. Based on the visible form of the .c ﬁles. Header Form % Occurrence % Uses Path Number Absolute Paths 75.0 86.4 0 "q-char-sequence" 25.0 17.2 0 Semantics 1897 A preprocessing directive of the form #include h-char-sequence # include new-line June 24, 2009 v 1.2
8. 1897 6.10.2 Source ﬁle inclusion × × × ×× × Occurrences of header name ×××××× × × 1,000 ××× ××× • "header" • ××× ×××× • ××× ××× ×××× • ×× ×××× ××× ×× • •• ××× ××× ×× ×× • • •••••••• ×× ×× ×× 100 •••••••• ×× ×× ×× ×× •••••••••• •••• • ×××× ×× ×× ×× ••••• ×××××× ••••• ••••• ×× ×× × •••••• ××××× •••••• ××××× ••••• •••••• ×××××× ••••••• ×××× × •••••• ××××× •••••• ××× 10 •••••×•××× •••••••××× × •••••××× • •••××× ×× •••••×× ×× ••••×× ×××× × ••••×× ••••× •••× ••××× ×× ×• •×× •×× •••• •••• ×••••• ×•×•• ××• •× ×• × 1 ×××•••• ×××•••• ×•••× ×××× ×•× •×× 1 10 100 1000 Rank Figure 1896.4: header-name rank (based on character sequences appearing in #include directives) plotted against the number of occurrences of each character sequence. Also see Figure 792.26. Fitting a power law using MLE for and "header-name" gives respective an exponent of -2.26, xmin = 8, and -1.8, xmin = 9. Based on the visible form of the .c ﬁles. searches a sequence of implementation-deﬁned places for a header identiﬁed uniquely by the speciﬁed sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. Commentary File systems invariably provide a unique method of identifying every ﬁle they contain (e.g., a full path name). The base document recognized the disadvantages of requiring that the full path name be speciﬁed in each #include directive and permitted a substring of it to be given. The implementation-deﬁned places are header name 918 usually additional character sequences (e.g., directory names) added to the h-char-sequence in an attempt syntax to create a full path name that refers to an existing ﬁle. Rationale The ﬁle search rules used for the ﬁlename in the #include directive were left as implementation-deﬁned. The Standard intends that the rules which are eventually provided by the implementor correspond as closely as possible to the original K&R rules. The primary reason that explicit rules were not included in the Standard is the infeasibility of describing a portable ﬁle system structure. It was considered unacceptable to include UNIX-like directory rules due to signiﬁcant differences between this structure and other popular commercial ﬁle system structures. Nested include ﬁles raise an issue of interpreting the ﬁle search rules. In UNIX C a #include directive found within an included ﬁle entails a search for the named ﬁle relative to the ﬁle system directory that holds the outer #include. Other implementations, including the earlier UNIX C described in K&R, always search relative to the same current directory. The C89 Committee decided in principle in favor of K&R approach, but was unable to provide explicit search rules as explained above. Other Languages Other languages (or an extension provided by their implementations) commonly use the double-quote delimited form. Common Implementations The character sequence between the < and > delimiters is invariably treated as the name of a ﬁle, possibly in- #include 1909 mapping to host ﬁle cluding a path. The ordering of the search sequence used for directives having the form is often different from that used for the form "q-char-sequence". For instance, in the case the contents of /usr/include might be searched ﬁrst, followed by the contents of the directory con- taining the .c ﬁle, while in "q-char-sequence" case the contents of the directory containing the .c ﬁle might be searched ﬁrst, followed by other places. v 1.2 June 24, 2009
17. 6.10.3 Macro replacement 1921 Commentary There was an existing body of code, containing redeﬁnitions of the same macro, when the C Standard was ﬁrst written. The C committee did not want to specify that existing code containing such usage was non-conforming, but they did consider the case where the bodies of any subsequent deﬁnitions differed to be an erroneous usage. 1983 EXAMPLE macro redeﬁnition C90 The wording in the C90 Standard was modiﬁed by the response to DR #089. Common Implementations Some translators permit multiple deﬁnitions of a macro, independently of the contents of the contents of the #deﬁne/#undef stack bodies. The behavior is for a new deﬁnition to cause the previous body to be pushed, in a stack-like fashion. Any subsequent #undef of the macro name popping this stacked deﬁnition and to make it the current one. Coding Guidelines C permits more than one deﬁnition of the same macro name, with the same body, and more than one external deﬁnition of the same object, with the same type and the coding guideline issues are the same for both (in 420 linkage 422.1 identiﬁer both cases translators are not always required to issue a diagnostic if the deﬁnitions are considered to be declared in one ﬁle different). In both cases a technique for avoiding duplicate deﬁnitions, during translation but not in the visible source, is to bracket deﬁnitions with #ifndef MACRO_NAME/#endif (in the case of the ﬁle scope object a macro name needs to be created and associated with its declaration). Using this technique has the disadvantage that it prevents the translator checking that any subsequent redeclarations of an identiﬁer are the same (unless the bracketing occurs around the only textual declaration that occurs in any source ﬁle used to build a program). 1920 Likewise, an identiﬁer currently deﬁned as a function-like macro shall not be redeﬁned by another #define function-like macro redeﬁnition preprocessing directive unless the second deﬁnition is a function-like macro deﬁnition that has the same number and spelling of parameters, and the two replacement lists are identical. Commentary 1919 object-like The issues are the same as for object-like macros, with the addition of checks on the parameters. Requiring macro redeﬁnition that the parameters be spelled the same, rather than, for instance, that they have an identical effect, simpliﬁes the similarity checking of two macro bodies. For instance, in: 1 #define FM(foo) ((foo) + x) 2 #define FM(bar) ((bar) + x) a translator is not required to deduce that the two deﬁnitions of FM are structurally identical. 1921 There shall be white-space between the identiﬁer and the replacement list in the deﬁnition of an object-like macro. Commentary In the following (assuming $is a member of the extended character set and permitted in an identiﬁer 216 extended character set preprocessing token): 1 #define A$ x an object-like macro with the name A$and the body x is deﬁned, not macro with the name A and the body$ x. There is no requirement that there be white-space following the ) in a function-like macro deﬁnition. C90 The response to DR #027 added the following requirements to the C90 Standard. DR #027 June 24, 2009 v 1.2
18. 1922 6.10.3 Macro replacement Correction Add to subclause 6.8, page 86 (Constraints): In the deﬁnition of an object-like macro, if the ﬁrst character of a replacement list is not a character required by subclause 5.2.1, then there shall be white-space separation between the identiﬁer and the replacement list.* [Footnote *: This allows an implementation to choose to interpret the directive: #define THIS$AND$THAT(a, b) ((a) + (b)) as deﬁning a function-like macro THIS$AND$THAT, rather than an object-like macro THIS. Whichever choice it makes, it must also issue a diagnostic.] However, the complex interaction between this speciﬁcation and UCNs was debated during the C9X review process and it was decided to simplify the requirements to the current C99 form. 1 #define TEN.1 /* Define the macro TEN to have the body .1 in C90. */ 2 /* A constraint violation in C99. */ C++ The C++ Standard speciﬁes the same behavior as the C90 Standard. Common Implementations HP–was DEC– treats \$ as part of the spelling of the macro name. If the identiﬁer-list in the macro deﬁnition does not end with an ellipsis, the number of arguments (including 1922 those arguments consisting of no preprocessing tokens) in an invocation of a function-like macro shall equal the number of parameters in the macro deﬁnition. Commentary function call 998 arguments agree with parameters This requirement is the macro invocation equivalent of the one for function calls. C90 If (before argument substitution) any argument consists of no preprocessing tokens, the behavior is undeﬁned. The behavior of the following was discussed in DR #003q3, DR #153, and raised against C99 in DR #259 (no committee response was felt necessary). 1 #define foo() A 2 #define bar(B) B 3 4 foo() // no arguments 5 bar() // one empty argument? What was undeﬁned behavior in C90 (an empty argument) is now explicitly supported in C99. The two most likely C90 translator undeﬁned behaviors are either to support them (existing source developed using such a translator will may contain empty arguments in a macro invocation), or to issue a diagnostic (existing source developed using such a translator will not contain any empty arguments in a macro invocation). C++ The C++ Standard contains the same wording as the C90 Standard. C++ translators are not required to correctly process source containing macro invocations having any empty arguments. v 1.2 June 24, 2009