Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should a compiler interpret an arbitrary non-zero value in bool as true correctly?

Bools are supposed to convert to 1 for true values and to 0 otherwise. However, that says nothing on how they may actually be stored in memory. What happens if I store an arbitrary non-zero value in a bool? Does the standard guarantee correct behavior when casting those to ints?

For example, given the following program,

#include <string.h>

int main()
{
  bool b;
  memset( &b, 123, sizeof( b ) );

  return b;
}

Does the standard guarantee the program would return 1?

like image 993
dragonroot Avatar asked Dec 30 '15 03:12

dragonroot


1 Answers

No, reading from that bool after the memset is (at least, see below) unspecified behaviour so there is no guarantee as to what value will be returned.

It might turn out that in the particular architecture, the value representation of a bool consists only of the high-order bit, in which case the value produced by broadcasting 123 over the byte(s) of the bool would be turn out to be a representation of false.

The C++ standard does not specify what the actual bit patterns representing the values true and false are. An implementation may use any or all of the bits in the object representation of a bool -- which must be at least one byte, but might be longer -- and it may map more than one bit pattern to the same value:

§3.9.1 [basic.fundamental]/1:

…For narrow character types, all bits of the object representation participate in the value representation. For unsigned narrow character types, each possible bit pattern of the value representation represents a distinct number. These requirements do not hold for other types.

Paragraph 6 of the same section requires values of type bool to be either true or false, but a footnote points out that in the face of undefined behaviour a bool "might behave as if it is neither true nor false." (That's obviously within the bounds of undefined behaviour; if a program exhibits UB, there are no requirements whatsoever on its execution, even before the UB is evidenced.)

Nothing in the standard permits using low-level memory copying operations on objects other than arrays of narrow chars, except for the case in which the object is trivially copyable and the object representation is saved by copying it to a buffer and later restored by copying it back. Any other use of C library functions which overwrite arbitrary bytes in an object representation should be undefined by the general definition of undefined behaviour ("[the standard] omits any explicit definition of behavior"). But I'm forced to agree that there is no explicit statement that memset is UB, and so I'll settle on unspecified behaviour, which seems quite clear since the representation of bool is certainly unspecified.

like image 192
rici Avatar answered Nov 15 '22 11:11

rici