1. Trang chủ
  2. » Công Nghệ Thông Tin

The New C Standard- P12

100 293 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 100
Dung lượng 670,29 KB

Nội dung

6.5.10 Bitwise AND operator 1238 Commentary The rationale for performing these conversions is a general one that is not limited to the operands of the 702 operators cause conversions arithmetic operators. C ++ The following conversion is presumably performed on the operands. 5.11p1 The usual arithmetic conversions are performed; Common Implementations If one of the operands is positive and has a type with lower rank than the other operand, it may be possible to make use of processor instructions that operate on narrower width values. (Converting the operand to the greater rank will cause it to be zero extended, which will cancel out any ones in the other operand.) Unless both operands are known to be positive, there tend to be few opportunities for optimizing occurrences of the ^ and | operators (because of the possibility that the result may be affected by an increase in value representation bits). Coding Guidelines Unless both operands have the same type, which also has a rank at least equal to that of int , these conversions will increase the number of value representation bits in one or both operands. Given that the binary & operator is defined to work at the bit level, developers have to invest additional effort in considering the effects of the usual arithmetic operands on the result of this operator. A probabilistic argument could be used to argue that of all the bitwise operators the & operator has the lowest probability of causing a fault through an unexpected increase in the number of value representation bits. For instance, the probability of both operands having a negative value (needed for any additional bits to be set in the result) is lower than the probability of one operand having a negative value (needed for a bit to be set in the result of the ^ and | operators). Unless the operands have a bit-set role, the guideline recommendation dealing with use of representation 945 bit-set role information is applicable here. 569.1 represen- tation in- formation using 1237 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). Commentary This information is usually expressed in tabular form. 0 1 0 0 0 1 0 1 Common Implementations The Unisys A Series [1423] uses signed magnitude representation. If the operands have an unsigned type, the bit used to represent the sign in signed types, which is present in the object representation on this processor, does not take part in the binary & operation. If the operands have a signed type, the sign bit does take part in the bitwise-AND operation. Coding Guidelines Although the result of the bitwise-AND operator is the common type derived from the usual arithmetic conversions, for the purpose of these guideline recommendations its role is the same as that of its operands. 706 usual arith- metic conver- sions 1352 object role 1238 92) Two objects may be adjacent in memory because they are adjacent elements of a larger array or adjacent footnote 92 members of a structure with no padding between them, or because the implementation chose to place them so, even though they are unrelated. June 24, 2009 v 1.2 6.5.11 Bitwise exclusive OR operator 1240 Commentary By definition elements of an array are contiguous and the standard specifies the relative order of members array contiguously allocated set of objects 526 structure members later compare later 1206 and their possible padding. Some implementations treat objects defined by different declarations in the same structure unnamed padding 1424 way as the declaration of members in a structure definition. For instance, assigning the same relative offsets to objects local to a function definition as they would the equivalent member declarations in a structure type. The issue of the layout of objects in storage is discussed elsewhere. storage layout 1354 This footnote lists all the cases where objects may be adjacent in memory. C90 The C90 Standard did not discuss these object layout possibilities. C ++ The C ++ Standard does not make these observations. Other Languages Most languages do not get involved in discussing this level of detail. Common Implementations Most implementations aim to minimize the amount of padding between objects. In many cases objects defined in block scope are adjacent in memory to objects defined textually adjacent to them in the source code. 1239 If prior invalid pointer operations (such as accesses outside array bounds) produced undefined behavior, subsequent comparisons also produce undefined behavior. Commentary This describes a special case of undefined behavior. (It is called out because, in practice, it is more likely to occur for values having pointer types than values having integer types.) Once undefined behavior has occurred, any subsequent operation can also produce undefined behavior. The standard does not limit the scope of undefined behaviors to operations involving operands that cause the initial occurrence. Common Implementations On many implementations the undefined behavior that occurs when additive operations, on values having an integer type, overflow is symmetrical. That is, an overflow in one direction can be undone by an overflow in the other direction (e.g., INT_MAX+2-2 produces the same result as INT_MAX-2+2 ). On implementations for processors using a segmented architecture this symmetrical behavior may not occur, for values having pointer segmented architecture 590 pointer types, because of internal details of how pointer arithmetic is handled on segment boundaries. On some processors additive operations, on integer or pointer types, saturate. In this case the undefined arithmetic saturated 687 behavior is not symmetrical. C90 The C90 Standard did not discuss this particular case of undefined behavior. 6.5.11 Bitwise exclusive OR operator 1240 exclusive-OR-expression: AND-expression exclusive-OR-expression ^ AND-expression Commentary The ^ operator can be replaced by a sequence of equivalent bitwise operators; for instance, x ^ y can be written (x & (~y)) | ((~x) & y) . However, most processors contain a bitwise exclusive-OR instruction and thus this operator is included in C. Being able to represent a bitwise operator using an equivalent sequence of other operators is not necessarily an argument against that operator being included in C. It is v 1.2 June 24, 2009 6.5.11 Bitwise exclusive OR operator 1242 possible to represent any boolean expression using a sequence of NAND (not and, e.g., !(x & y) ) operators; for instance, !x becomes x NAND x , x & y becomes (x NAND y) NAND (x NAND y) , and so on. Although this equivalence may be of practical use in hardware design (where use of mass-produced circuits performing a single boolean operation can reduce costs), it is not applicable to software. Other Languages Languages that support bitwise operations usually support an exclusive-OR operator. The keyword xor is sometimes used to denote this operator. The ^ character is used as a token to indicate pointer indirection in Pascal and Ada. Coding Guidelines The exclusive-OR operator is not encountered in everyday life. There is no English word or phrase that expresses its semantics. The everyday usage discussed in the subclause on the logical-OR operator is based 1256 logical-OR- expression syntax on selecting between two alternatives (e.g., either one or the other which only deals with two of the four possible combinations of operand values). Because of the lack of everyday usage, and because it does not occur often within C source (compared with bitwise-AND and bitwise-OR (see Table 912.2)) it is to be expected that developers will have to expend more effort in comprehending the consequences of this operator when it is encountered in source code. The greater cognitive cost associated with use of the exclusive-OR operator is not sufficient to recommend against its use. Developers need to be able to make use of an alternative that has a lower cost. While the behavior of the exclusive-OR operator can be obtained by various combinations of other bitwise operators, it seems unlikely that the cost of comprehending any of these sequences of operators will be less than that of the operator they replace. If the exclusive-OR operator appears within a more complicated boolean expression it may be possible to rewrite that expression in an alternative form. Rewriting an expression can increase 1248.1 boolean expression minimize effort the cognitive effort needed for readers to map between source code and the application domain (i.e., if the conditions in the application domain are naturally expressed in terms of a sequence of operators that include exclusive-OR). The cost/benefit of performing such a rewrite needs to be considered on a case by case basis. Example The ^ operator is equivalent to the binary + operator if its operands do not have any set bits in common. This property can be used to perform simultaneous addition on eight digits represented in packed BCD [698] (i.e., four bits per digit). 1 int BCD_add(a, b) 2 { 3 int t1 = a + 0x06666666, 4 t2 = t1 + b, 5 t3 = t1 ^ b, 6 t4 = t2 ^ t3, 7 t5 = ~t4 & 0x11111110, 8 t6 = (t5 >> 2) | (t5 >> 3); 9 return t2 - t6; 10 } Usage The ^ operator represents 1.2% of all occurrences of bitwise operators in the visible source of the .c files. Constraints 1241 Each of the operands shall have integer type. Commentary The discussion for the various subsections is the same as those for the bitwise AND operator. 1235 & binary operand type Semantics June 24, 2009 v 1.2 6.5.12 Bitwise inclusive OR operator 1244 1242 The usual arithmetic conversions are performed on the operands.^ operands con- verted Commentary The discussion in the various subsections is the same as that for the bitwise AND operator. & binary operands converted 1236 1243 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). Commentary This information is usually expressed in tabular form. 0 1 0 0 1 1 1 0 Common Implementations The Unisys A Series [1423] uses signed magnitude representation. If the operands have an unsigned type, the sign bit is not affected by the bitwise complement operator. If the operands have a signed type, the sign bit does take part in the bitwise complement operation. The bitwise exclusive-OR instruction is sometimes generated, by optimizers, to swap the contents of two registers, without using a temporary register (as shown in the Example below). Coding Guidelines Although the result of the bitwise exclusive-OR operator is the common type derived from the usual arithmetic conversions, for the purpose of these guideline recommendations its role is the same as that of its operands. usual arith- metic con- versions 706 object role 1352 Example 1 #define SWAP(x, y) (x=(x ^ y), y=(x ^ y), x=(x ^ y)) 2 #define UNDEFINED_SWAP(x, y) (x ^= y ^= x ^= y) / * Requires right to left evaluation. * / 6.5.12 Bitwise inclusive OR operator 1244 inclusive-OR- expression syntax inclusive-OR-expression: exclusive-OR-expression inclusive-OR-expression | exclusive-OR-expression Commentary The discussion on AND-expression is applicable here. AND- expression syntax 1234 Coding Guidelines The | and || operators differ from their corresponding AND operators in that the zero/nonzero status of their result is always the same, even though the actual result values are likely to differ. 0x10 | 0x01 ⇒ 0x11 0x10 || 0x01 ⇒ 1 While it is possible to use either operators in a context where the result is compared against zero, the guideline recommendation dealing with matching an operator to the role of its result still applies. The pattern role operand matching 1234 of operator context usage (see Table 1244.1) is similar to that of the two AND operators. v 1.2 June 24, 2009 6.5.12 Bitwise inclusive OR operator 1247 Table 1244.1: Occurrence of the | and || operator (as a percentage of all occurrences of each operator; the parenthesized value is the percentage of all occurrences of the context that contains the operator). Based on the visible form of the .c files. Context | || if control-expression 8.8 ( 0.7) 86.0 ( 6.9) other contexts 90.7 (—) 11.9 (—) while control-expression 0.3 ( 0.5) 1.9 ( 2.7) for control-expression 0.0 ( 0.0) 0.3 ( 0.2) switch control-expression 0.1 ( 0.3) 0.0 ( 0.0) Constraints 1245 Each of the operands shall have integer type. Commentary The discussion for the various subsections is the same as those for the bitwise AND operator. 1235 & binary operand type Semantics 1246 The usual arithmetic conversions are performed on the operands. Commentary The discussion in the various subsections is the same as that for the bitwise exclusive-OR operator. 1242 ^ operands con- verted 1247 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). Commentary This information is usually expressed in tabular form. 0 1 0 0 1 1 1 1 Common Implementations The Unisys A Series [1423] uses signed magnitude representation. If the operands have an unsigned type, the sign bit is not affected by the bitwise-OR operator. If the operands have a signed type, the sign bit does take part in the bitwise-OR operation. Numeric value Occurrences 0 1632 64 100 128150 200 255 1 10 100 binary | × decimal notation • hexadecimal notation × • × • × • × • × • × • × • × • × • × • × • × • × • × • × • × • × • × • × × × • × • • • • × • • • × • × • × • × • • • • ••• ×× • • × •• • × • •• • • • • • × • • • • • • • ••• • × • ••• • × • • × • •• • •• • • • •• • × • × • Figure 1244.1: Number of integer-constant s having a given value appearing as the right operand of the bitwise-OR operator. Based on the visible form of the .c files. June 24, 2009 v 1.2 6.5.13 Logical AND operator 1248 Coding Guidelines Although the result of the bitwise inclusive-OR operator is the common type derived from the usual arithmetic conversions, for the purpose of these guideline recommendations its role is the same as that of its operands. usual arith- metic con- versions 706 object role 1352 6.5.13 Logical AND operator 1248 logical-AND- expression syntax logical-AND-expression: inclusive-OR-expression logical-AND-expression && inclusive-OR-expression Commentary The relative precedence of the binary && and || operators is the same as that of the binary & and | operators. Other Languages In many languages the logical-AND operator has higher precedence than the logical-OR operator. In a few languages (Ada, Fortran which uses the keyword .AND. ), they have the same precedence. Ada supports two kinds of logical-AND operations: and and and then , the latter having the same semantics as the bitwise & 1234 logical-AND operator in C (short-circuit evaluation). These operators also have the same precedence as the logical-OR and logical-XOR operators. Coding Guidelines The issue of swapping usages of the & and && operators is discussed elsewhere. AND- expression syntax 1234 There are a number of techniques for simplifying expressions involving boolean values. One of the most commonly used methods is the Karnaugh map. [725] (For equations involving more than five operands, the Quine-McCluskey technique [1388] may be more applicable; this technique is also capable of being automated.), while some people prefer algebraic manipulation (refer to Table 1248.1). Although simplification may lead to an expression that requires less reader effort to comprehend as a boolean expression, the resulting expression may require more effort to map to the model of the application domain being used. For instance, (A && (!B)) || ((!A) && B) can be simplified to A ^ B (assuming A and B only take the values 0 and 1, otherwise another operation is required). However, while the use of the exclusive-OR operator results in a visually simpler expression, developers have much less experience dealing with it than the other bitwise and logical operators. There is also the possibility that, for instance, the expression (A && (!B)) occurs in other places within the source and has an easily-deduced meaning within the framework of the application model. Logical operators are part of mathematical logic. Does the human mind contain special circuitry that mind logical operator performs this operation, just like most processors contain a group of transistors that perform this C operation? Based on experimental observations, the answer would appear to be no. So how does the human mind handle the logical-AND operation? One proposal is that people learn the rules of this operator by rote so that they can later be retrieved from memory. The result of a logical operation is then obtained by evaluating each operand’s condition to true or false and performing a table lookup using previously the learned logical-AND table to find the result. Such an approach relies on short-term memory, and the limited capacity of short-term memory offers one explanation of why people are poor at evaluating moderately complex logical operators in their head. There is insufficient capacity to hold the values of the operands and the intermediate results. The form of logical deduction that is needed in comprehending software rarely occurs in everyday life. People’s ability to solve what appear to be problems in logic does not mean that the methods of boolean mathematics are used. A number of other proposals have been made for how people handle logical problems in everyday life. One is that the answers to the problems are simply remembered; after many years of life experience, people accumulate a store of knowledge on how to deal with different situations. Studies have found that belief in a particular statement being true can cause people to ignore its actual status as a mathematical expression (i.e., people believe what they consider to be true rather than logically evaluating v 1.2 June 24, 2009 6.5.13 Logical AND operator 1248 the true status of an expression). Estimating developers’ performance at handling logical expressions therefore involves more than a model of how they process mathematical logic. While minimizing the number of operands in a boolean expression may have appeal to mathematically oriented developers, the result may be an expression that requires more effort to comprehend. It is not yet possible to calculate the reader effort required to comprehend a particular boolean expression. For this reason the following guideline recommendation relies on the judgment of those performing the code review. Rev 1248.1 Boolean expressions shall be written in a form that helps minimize the effort needed by readers to comprehend them. A comment associated with the simplified expression can be notated in at least two ways: using equations or by displaying the logic table. Few developers are sufficiently practiced at boolean algebra to be able to fluently manipulate expressions; a lot of thought is usually required. A logic table highlights all combinations of operands and, for small numbers of inputs, is easily accommodated in a comment. Table 1248.1: Various identities in boolean algebra expressed using the || and && operators. Use of these identities may change the number of times a particular expression is evaluated (which is sometimes the rationale for rewriting it). The relative order in which expressions are evaluated may also change (e.g., when A==1 and B==0 in (A && B) || (A && C) the order of evaluation is A⇒ B⇒ A⇒ C, but after use of the distributive law the order becomes A⇒ B⇒ C). Relative Order Preserved Expression ⇒ Alternative Representation Distributive laws no (A && B) || (A && C) ⇒ A && (B || C) no (A || B) && (A || C) ⇒ A || (B && C) DeMorgan’s theorem yes !(A || B) ⇒ (!A) && (!B) yes !(A && B) ⇒ (!A) || (!B) Other identities yes A && ((!A) || B) ⇒ A && B yes A || ((!A) && B) ⇒ A || B The consensus identities no (A && B) || ((!A) && C) || (B && C) ⇒ (A && B) || ((!A) && C)) yes (A && B) || (A && (!B) && C) ⇒ (A && B) || (A && C) yes (A && B) || ((!A) && C) ⇒ ((!A) || B) && (A || C) An expression containing a number of logical operators, each having operands whose evaluation involves relational or equality operators, can always be written in a number of different ways, for instance: 1 if ((X < 4) && !(Y || (Z == 1))) 2 / * . * / 3 4 if ((Y != 0) && (Z != 0) && (X < 4)) 5 / * . * / 6 7 if (!((X >= 4) || Y || (Z == 1))) 8 / * . * / 9 10 if (X < 4) 11 if (!(Y || (Z == 1))) 12 / * . * / An example of complexity in an English sentence might be “Suppose five days after the day before yesterday is Friday. What day of the week is tomorrow?” Whether the use of a less complex (i.e., having less cognitive load) expression has greater cost/benefit than explicitly calling out the details of the calculation needs to be determined on a case-by-case basis. June 24, 2009 v 1.2 6.5.13 Logical AND operator 1250 A study by Feldman [423] found that the subjective difficulty of a concept (e.g., classifying colored polygons of various sizes) was directly proportional to its boolean complexity (i.e., the length of the shortest logically categoriza- tion per- formance predicting 0 equivalent propositional formula). Table 1248.2: Common token pairs involving && , or || (as a percentage of all occurrences of each token). Based on the visible form of the .c files. Note: entries do not always sum to 100% because several token sequences that have very low percentages are not listed. Token Sequence % Occurrence of First Token % Occurrence of Second Token Token Sequence % Occurrence of First Token % Occurrence of Second Token identifier && 0.4 48.5 && defined 0.9 6.2 ) || 0.9 42.7 || ! 11.3 6.0 identifier || 0.2 39.3 character-constant || 4.2 4.2 ) && 1.1 34.9 character-constant && 5.3 3.3 || defined 4.8 21.0 && ( 28.7 0.9 integer-constant || 0.3 12.4 || ( 29.7 0.6 integer-constant && 0.4 11.5 && identifier 53.9 0.5 && ! 13.5 11.3 || identifier 51.8 0.3 Constraints 1249 Each of the operands shall have scalar type.&& operand type Commentary The behavior is defined in terms of an implicit comparison against zero, an operation which is only defined for operands having a scalar type in C. C ++ 5.14p1 The operands are both implicitly converted to type bool (clause 4). Boolean conversions (4.12) covers conversions for all of the scalar types and is equivalent to the C behavior. Other Languages Languages that support boolean types usually require that the operands to their logical-AND operator have boolean type. Coding Guidelines The discussion on the bitwise-AND operator is also applicable here, and the discussion on the comprehension & binary operand type 1235 of the controlling expression in an if statement is applicable to both operands. if statement controlling expression scalar type 1743 Table 1249.1: Occurrence of logical operators having particular operand types (as a percentage of all occurrences of each operator; an _ prefix indicates a literal operand). Based on the translated form of this book’s benchmark programs. Left Operand Operator Right Operand % Left Operand Operator Right Operand % int || int 87.7 _long || _long 2.2 int && int 73.9 int && ptr-to 2.2 other-types && other-types 12.8 int && char 1.8 other-types || other-types 8.4 int || _long 1.7 ptr-to && int 4.5 int && _int 1.3 char && int 2.3 ptr-to && ptr-to 1.1 Semantics v 1.2 June 24, 2009 6.5.13 Logical AND operator 1250 1250 The && operator shall yield 1 if both of its operands compare unequal to 0; && operand com- pare against 0 Commentary The only relationship between the two operands is their appearance together in a logical-AND operation. There is no benefit, from the implementations point of view, in performing the usual arithmetic conversions or the integer promotions on each operand. It is sometimes necessary to test a preliminary condition before the main condition can be tested. For instance, it may be necessary to check that a pointer value is not null before dereferencing it. The test could be performed using nested if statements, as in: 1 if (px != NULL) 2 if (px->m1 == 1) More complex conditions are likely to involve the creation of a warren of nested if statements. The original designers of the C language decided that it was worthwhile creating operators to provide a shorthand notation (i.e., the logical-AND and logical-OR operators). In the preceding case use of one of these operators allows both tests to be performed within a single conditional expression (e.g., if ((px != NULL) && (px->m1 == 1)) ). The other advantage of this operator, over nested if statements, is in the creation of expressions via the expansion of nested macro invocations. Generating nested if statements requires the use of braces to ensure that any following else arms are associated with the intended if arm. Generating these braces introduces additional complexities (at least another macro invocation in the source) that don’t occur when the && operator is used. C ++ 5.14p1 The result is true if both operands are true and false otherwise. The difference in operand types is not applicable because C ++ defines equality to return true or false . The difference in return value will not cause different behavior because false and true will be converted to 0 and 1 when required. Other Languages The mathematical use of this operator returns true if both operands are true. Languages that support a boolean data type usually follow this convention. Common Implementations As discussed elsewhere, loading a value into a register often sets conditional flags as does a relational 1111 logical negation result is operation comparing two values. This means that in many cases machine code to compare against zero need 1210 relational operators result value not be generated, as in, the following condition: 1 if ((a == b) && (c < d)) which is likely to generate an instruction sequence of the form: compare a with b if not equal jump to else_or_endif compare c with d if greater than or equal to jump to else_or_endif code for if arm else_or_endif: rest of program June 24, 2009 v 1.2 6.5.13 Logical AND operator 1253 Coding Guidelines Should the operands always be explicitly compared against zero? When an operand is the result of a relational or equality operator, such a comparison is likely to look very unusual: 1 if (((a == b) == 0) && ((c < d) == 0)) It is assumed that developers think about the operands in terms of boolean roles and the result of both the relational and equality operators have a boolean role. In these cases another equality comparison is redundant. When an operand does not have a boolean role, an explicit comparison against zero might be appropriate (these issues are also discussed elsewhere). ! equivalent to 1113 selection statement syntax 1739 1251 otherwise, it yields 0. Commentary That is, a value of zero having type int. 1252 The result has type int.&& result type Commentary The rationale for this choice is the same as for relational operators. relational operators result type 1211 C ++ 5.14p2 The result is a bool. The difference in result type will result in a difference of behavior if the result is the immediate operand of the sizeof operator. Such usage is rare. Other Languages In languages that support a boolean type, the result of logical operators usually has a boolean type. Common Implementations If the result is immediately cast to another type, an implementation may choose to arrange that other type as the result type; for instance, in: 1 float f(int ip) 2 { 3 return (ip > 0) && (ip < 10); 4 } an implementation may choose to return 0.0 and 1.0 as the result of the expression evaluation, saving a cast operation. Coding Guidelines The coding guideline issues are the same as those for the relational operators. relational operators result type 1211 1253 Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation;&& evaluation order Commentary The left-to-right evaluation order of the && operator is required; it is what makes it possible for the left operand to verify a precondition for the evaluation of the right operand. There is no requirement that the evaluation of the right operand, if it occurs, take place immediately after the evaluation of the left operand. Coding Guidelines This issue is covered by the guideline recommendation dealing with sequence points. sequence points all orderings give same value 187.1 v 1.2 June 24, 2009 [...]... 1255.1 shows the possible conditions Using modified condition, MC, coverage can significantly reduce the number of test cases over branch condition, BC, coverage Table 1255.1: Truth table showing how each operand of (A || (B && C) ) can affect its result Case 1 and 2 show that A affects the outcome; Case 3 shows that B affects the outcome; Case 3 and 4 shows that C affects the outcome Case A B C Result 1... stages The appropriate qualifiers, for example, do not depend on whether the two pointers have compatible types 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... and when it is specified, a sequence point also occurs This C sentence effectively specifies that there is no requirement for implementations to support developer access to these temporary objects C9 0 This sentence did not appear in the C9 0 Standard and had to be added to C9 9 because of a change in the definition of the term lvalue 721 lvalue C+ + The C+ + definition of lvalue is the same as C9 0, so this wording... values being accessed from registers in C9 0 while they will be accessed from storage in C9 9 C+ + The C+ + Standard explicitly specifies the behavior for creating a composite pointer type (5.9p2) which is returned in this case Coding Guidelines 1216 The coding guideline discussion on the equality operators is applicable here pointer to incomplete type Example 1 2 equality operators const int *p_ci; volatile... statement form, there is no guaranteed sequence after the evaluation of the second operand, if it occurs C+ + All side effects of the first expression except for destruction of temporaries (12.2) happen before the second expression is evaluated 5.14p2 1025 The possible difference in behavior is the same as for the function-call operator function call sequence point Coding Guidelines While the sequence point... elsewhere syntax Constraints 1257 Each of the operands shall have scalar type Commentary The discussions in the various subsections of the logical-AND operator are applicable here 1249 && operand type C+ + The operands are both implicitly converted to bool (clause 4) 5.15p1 Boolean conversions (4.12) covers conversions for all of the scalar types and is equivalent to the C behavior Semantics 1258 The || operator... verify that all combinations of A, B, and C, are evaluated In the case of the condition involving A, B, and C eight separate test cases are needed For more complex conditions, the number of test cases rapidly becomes impractical Modified condition decision testing requires that test cases be written to demonstrate that each operand can independently affect the output of the decision For the if statement... is the same as for the function-call operator The second operand is evaluated only if the first compares unequal to 0; 1275 Commentary Because the operand might not be evaluated, replacing a conditional operator by a function call, taking three arguments, would not have the same semantics Coding Guidelines && 1255 second operand The guideline discussion on the logical-AND operator is applicable here the. .. sequence point This is a requirement on the implementation Like other operators that generate side effects, the exact time when the side effect occurs is not specified, only the bounds between when it must occur Most assignment operators occur in the context of an expression statement, which is a full expression and hence has a sequence point after its evaluation C+ + The C+ + Standard does not explicitly... which case the other operand is converted to type pointer to void, and the result has that type C9 0 did not add any qualifies to the pointer to void type In the case of the const qualifier this difference would not have been noticeable (the resulting pointer type could not have been dereferenced without an explicit cast to modify the pointed-to object) In the case of the volatile qualifier this difference . listed. Token Sequence % Occurrence of First Token % Occurrence of Second Token Token Sequence % Occurrence of First Token % Occurrence of Second Token identifier. && C) ) can affect its result. Case 1 and 2 show that A affects the outcome; Case 3 shows that B affects the outcome; Case 3 and 4 shows that C affects the

Ngày đăng: 24/10/2013, 08:15