Prev: _in s and _out s ?
Next: MSI Serial Number Validation
From: Geoff on 1 May 2010 20:04 On Sat, 01 May 2010 14:41:09 -0500, "Doug Harrison [MVP]" <dsh(a)mvps.org> wrote: >On Fri, 30 Apr 2010 17:35:24 +0200, Simon <bad(a)example.com> wrote: > >>> And you should not compare a bool variable to a bool literal; this is poor style. What >>> value to you think a bool variable has? And why aren't you just saying >> >>This is your style, I don't agree with it. > >It's not just bad style, it's bad practice. When you compare to the bool >literal "true", the other side of the expression had better well be an >actual bool variable. Otherwise, if it's non-zero but not exactly equal to >1, then the test "x == true" will fail for the non-bool x, even though any >non-zero value is considered true in C++ and C. In Windows and MFC >programming, you will frequently deal with BOOL, a typedef for int, for >which it is an unequivocal blunder to compare to TRUE. Making special >exceptions for the C++ bool type just introduces complexity for no reason >at all, and FWIW, I don't know anyone who does it. All I see and use for >bools is x and !x. What would you say about a practice like this? typedef enum {false, true} qboolean; qboolean funct(int arg) { if (something) /* do something */ return true; else /* do something else*/ return false; }
From: Joseph M. Newcomer on 1 May 2010 22:32 My own view is that this is also bad practice. You are defining a type that you expect to have values {0, 1} but in fact I do not think that 'true' and 'false' of C++ are required to be specific values, just distinguished values which in the context of a bool expression will yield known results. So it seems risky. It is also redundant, since C++ defines 'true' and 'false' as reserved words and therefore it probably won't compile. It is also bad practice to write C code that is not compatible with the C++ language because you don't know who is going to use your files. Overall, the only valid expressions with bool involve the operators !, &&, ||, and perhaps ^, but should not involve == or !=. joe On Sat, 01 May 2010 17:04:02 -0700, Geoff <geoff(a)invalid.invalid> wrote: >On Sat, 01 May 2010 14:41:09 -0500, "Doug Harrison [MVP]" ><dsh(a)mvps.org> wrote: > >>On Fri, 30 Apr 2010 17:35:24 +0200, Simon <bad(a)example.com> wrote: >> >>>> And you should not compare a bool variable to a bool literal; this is poor style. What >>>> value to you think a bool variable has? And why aren't you just saying >>> >>>This is your style, I don't agree with it. >> >>It's not just bad style, it's bad practice. When you compare to the bool >>literal "true", the other side of the expression had better well be an >>actual bool variable. Otherwise, if it's non-zero but not exactly equal to >>1, then the test "x == true" will fail for the non-bool x, even though any >>non-zero value is considered true in C++ and C. In Windows and MFC >>programming, you will frequently deal with BOOL, a typedef for int, for >>which it is an unequivocal blunder to compare to TRUE. Making special >>exceptions for the C++ bool type just introduces complexity for no reason >>at all, and FWIW, I don't know anyone who does it. All I see and use for >>bools is x and !x. > >What would you say about a practice like this? > >typedef enum {false, true} qboolean; > >qboolean funct(int arg) >{ > if (something) >/* do something */ > > return true; > > else > >/* do something else*/ > return false; >} Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Geoff on 2 May 2010 00:57 On Sat, 01 May 2010 22:32:03 -0400, Joseph M. Newcomer <newcomer(a)flounder.com> wrote: >My own view is that this is also bad practice. You are defining a type that you expect to >have values {0, 1} but in fact I do not think that 'true' and 'false' of C++ are required >to be specific values, just distinguished values which in the context of a bool expression >will yield known results. So it seems risky. It is also redundant, since C++ defines >'true' and 'false' as reserved words and therefore it probably won't compile. It is also >bad practice to write C code that is not compatible with the C++ language because you >don't know who is going to use your files. > >Overall, the only valid expressions with bool involve the operators !, &&, ||, and perhaps >^, but should not involve == or !=. > joe > I thought you might say something like that. It does compile correctly and has since 1996 or so. It's very old code, inherited and admittedly very C-ish. As for the value of bool in C from N1336 ISO/IEC 9899:201x: 7.16 Boolean type and values <stdbool.h> 1 The header <stdbool.h> defines four macros. 2 The macro bool expands to _Bool. 3 The remaining three macros are suitable for use in #if preprocessing directives. They are true which expands to the integer constant 1, false which expands to the integer constant 0, and __bool_true_false_are_defined which expands to the integer constant 1. 4 Notwithstanding the provisions of 7.1.3, a program may undefine and perhaps then redefine the macros bool, true, and false.) As for it's value in C++, an excerpt from ISO/IEC JTC1 SC22 WG21 N3092 the draft standard for C++0x, I call your attention to 4.7.4 : 4.7 Integral conversions [conv.integral] 1 A prvalue of an integer type can be converted to a prvalue of another integer type. A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type. 2 If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [ Note: In a two�s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). �end note ] 3 If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined. 4 If the destination type is bool, see 4.12. If the source type is bool, the value false is converted to zero and the value true is converted to one. 5 The conversions allowed as integral promotions are excluded from the set of integral conversions. .... 4.12 Boolean conversions [conv.bool] 1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. A prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false. .... And N3092 9.6.4: If the value true or false is stored into a bit-field of type bool of any size (including a one bit bit-field), the original bool value and the value of the bit-field shall compare equal. If the value of an enumerator is stored into a bit-field of the same enumeration type and the number of bits in the bit-field is large enough to hold all the values of that enumeration type (7.2), the original enumerator value and the value of the bit-field shall compare equal. enum BOOL { FALSE=0, TRUE=1 }; struct A { BOOL b:1; }; A a; void f() { a.b = TRUE; if (a.b == TRUE) // yields true { /* ... */ } }
From: Joseph M. Newcomer on 2 May 2010 12:10 It is a common reasoning that "it compiles" justifies weird and potentially unmaintainable programming practices. I've even heard it argued that any syntactically correct program is an instance of good programming! Actually, the art form is a good deal deeper than syntax; I don't buy the "but it compiles" argument as a justification for any style. joe On Sat, 01 May 2010 21:57:45 -0700, Geoff <geoff(a)invalid.invalid> wrote: >On Sat, 01 May 2010 22:32:03 -0400, Joseph M. Newcomer ><newcomer(a)flounder.com> wrote: > >>My own view is that this is also bad practice. You are defining a type that you expect to >>have values {0, 1} but in fact I do not think that 'true' and 'false' of C++ are required >>to be specific values, just distinguished values which in the context of a bool expression >>will yield known results. So it seems risky. It is also redundant, since C++ defines >>'true' and 'false' as reserved words and therefore it probably won't compile. It is also >>bad practice to write C code that is not compatible with the C++ language because you >>don't know who is going to use your files. >> >>Overall, the only valid expressions with bool involve the operators !, &&, ||, and perhaps >>^, but should not involve == or !=. >> joe >> > >I thought you might say something like that. It does compile correctly >and has since 1996 or so. It's very old code, inherited and admittedly >very C-ish. > >As for the value of bool in C from N1336 ISO/IEC 9899:201x: > > 7.16 Boolean type and values <stdbool.h> > > 1 The header <stdbool.h> defines four macros. > > 2 The macro bool expands to _Bool. > > 3 The remaining three macros are suitable for use in #if > preprocessing directives. They are true which expands to the > integer constant 1, false which expands to the integer constant 0, >and __bool_true_false_are_defined which expands to the integer > constant 1. > > 4 Notwithstanding the provisions of 7.1.3, a program may undefine > and perhaps then redefine the macros bool, true, and false.) > >As for it's value in C++, an excerpt from ISO/IEC JTC1 SC22 WG21 N3092 >the draft standard for C++0x, I call your attention to 4.7.4 : > > 4.7 Integral conversions [conv.integral] > > 1 A prvalue of an integer type can be converted to a prvalue of > another integer type. A prvalue of an unscoped enumeration type > can be converted to a prvalue of an integer type. > > 2 If the destination type is unsigned, the resulting value is the > least unsigned integer congruent to the source integer (modulo 2n > where n is the number of bits used to represent the unsigned > type). [ Note: In a two�s complement representation, this > conversion is conceptual and there is no change in the bit pattern >(if there is no truncation). �end note ] > > 3 If the destination type is signed, the value is unchanged if it > can be represented in the destination type (and bit-field width); > otherwise, the value is implementation-defined. > > 4 If the destination type is bool, see 4.12. If the source type is > bool, the value false is converted to zero and the value true is > converted to one. > > 5 The conversions allowed as integral promotions are excluded from > the set of integral conversions. > >... > > 4.12 Boolean conversions [conv.bool] > > 1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer >to member type can be converted to a prvalue of type bool. A zero > value, null pointer value, or null member pointer value is > converted to false; any other value is converted to true. A > prvalue of type std::nullptr_t can be converted to a prvalue of > type bool; the resulting value is false. > >... > >And N3092 9.6.4: > > If the value true or false is stored into a bit-field of type bool > of any size (including a one bit bit-field), the original bool value >and the value of the bit-field shall compare equal. If the value of > an enumerator is stored into a bit-field of the same enumeration > type and the number of bits in the bit-field is large enough to hold >all the values of that enumeration type (7.2), the original > enumerator value and the value of the bit-field shall compare equal. >enum BOOL { FALSE=0, TRUE=1 }; > >struct A { > BOOL b:1; >}; > >A a; > >void f() { > a.b = TRUE; > if (a.b == TRUE) // yields true > { /* ... */ } >} Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Geoff on 2 May 2010 14:28
You speculated that it wouldn't compile. I refuted that speculation. And you completely ignored what the standards and drafts say about the value of true and false in C and C++. They are in fact required to have specific values. When faced with legacy code one is forced to accommodate a certain amount of "bad practices" much like the return (TRUE) or typedef int BOOL of the Windows API. On Sun, 02 May 2010 12:10:50 -0400, Joseph M. Newcomer <newcomer(a)flounder.com> wrote: >It is a common reasoning that "it compiles" justifies weird and potentially unmaintainable >programming practices. I've even heard it argued that any syntactically correct program >is an instance of good programming! > >Actually, the art form is a good deal deeper than syntax; I don't buy the "but it >compiles" argument as a justification for any style. > joe > >On Sat, 01 May 2010 21:57:45 -0700, Geoff <geoff(a)invalid.invalid> wrote: > >>On Sat, 01 May 2010 22:32:03 -0400, Joseph M. Newcomer >><newcomer(a)flounder.com> wrote: >> >>>My own view is that this is also bad practice. You are defining a type that you expect to >>>have values {0, 1} but in fact I do not think that 'true' and 'false' of C++ are required >>>to be specific values, just distinguished values which in the context of a bool expression >>>will yield known results. So it seems risky. It is also redundant, since C++ defines >>>'true' and 'false' as reserved words and therefore it probably won't compile. It is also >>>bad practice to write C code that is not compatible with the C++ language because you >>>don't know who is going to use your files. >>> >>>Overall, the only valid expressions with bool involve the operators !, &&, ||, and perhaps >>>^, but should not involve == or !=. >>> joe >>> >> >>I thought you might say something like that. It does compile correctly >>and has since 1996 or so. It's very old code, inherited and admittedly >>very C-ish. >> >>As for the value of bool in C from N1336 ISO/IEC 9899:201x: >> >> 7.16 Boolean type and values <stdbool.h> >> >> 1 The header <stdbool.h> defines four macros. >> >> 2 The macro bool expands to _Bool. >> >> 3 The remaining three macros are suitable for use in #if >> preprocessing directives. They are true which expands to the >> integer constant 1, false which expands to the integer constant 0, >>and __bool_true_false_are_defined which expands to the integer >> constant 1. >> >> 4 Notwithstanding the provisions of 7.1.3, a program may undefine >> and perhaps then redefine the macros bool, true, and false.) >> >>As for it's value in C++, an excerpt from ISO/IEC JTC1 SC22 WG21 N3092 >>the draft standard for C++0x, I call your attention to 4.7.4 : >> >> 4.7 Integral conversions [conv.integral] >> >> 1 A prvalue of an integer type can be converted to a prvalue of >> another integer type. A prvalue of an unscoped enumeration type >> can be converted to a prvalue of an integer type. >> >> 2 If the destination type is unsigned, the resulting value is the >> least unsigned integer congruent to the source integer (modulo 2n >> where n is the number of bits used to represent the unsigned >> type). [ Note: In a two�s complement representation, this >> conversion is conceptual and there is no change in the bit pattern >>(if there is no truncation). �end note ] >> >> 3 If the destination type is signed, the value is unchanged if it >> can be represented in the destination type (and bit-field width); >> otherwise, the value is implementation-defined. >> >> 4 If the destination type is bool, see 4.12. If the source type is >> bool, the value false is converted to zero and the value true is >> converted to one. >> >> 5 The conversions allowed as integral promotions are excluded from >> the set of integral conversions. >> >>... >> >> 4.12 Boolean conversions [conv.bool] >> >> 1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer >>to member type can be converted to a prvalue of type bool. A zero >> value, null pointer value, or null member pointer value is >> converted to false; any other value is converted to true. A >> prvalue of type std::nullptr_t can be converted to a prvalue of >> type bool; the resulting value is false. >> >>... >> >>And N3092 9.6.4: >> >> If the value true or false is stored into a bit-field of type bool >> of any size (including a one bit bit-field), the original bool value >>and the value of the bit-field shall compare equal. If the value of >> an enumerator is stored into a bit-field of the same enumeration >> type and the number of bits in the bit-field is large enough to hold >>all the values of that enumeration type (7.2), the original >> enumerator value and the value of the bit-field shall compare equal. >>enum BOOL { FALSE=0, TRUE=1 }; >> >>struct A { >> BOOL b:1; >>}; >> >>A a; >> >>void f() { >> a.b = TRUE; >> if (a.b == TRUE) // yields true >> { /* ... */ } >>} |