Using memcpy to copy an int to a char array and then print its elements: undefined behavior?

Consider the following code:

int i = 1; char c[sizeof (i)]; memcpy(c, &i, sizeof (i)); cout << static_cast<int>(c[0]); 

Please ignore if this is good code. I know that the output depends on the content capacity of the system. This is just an academic question.

This code:

  • Undefined behavior
  • Implementation-Defined Behavior
  • Clear behavior
  • Something else
+6
source share
3 answers

The rule you are looking for is 3.9p4:

The object representation of an object of type T is a sequence of objects N unsigned char occupied by an object of type T , where N is equal to sizeof(T) . The representation of an object value is a set of bits that hold a value of type T For trivially copied types, a value representation is a set of bits in an object representation that defines a value that is one discrete element of a particular set of values.

So, if you use unsigned char , you will get the behavior defined by the implementation (any appropriate implementation should give you a guarantee of what it is).

Reading through char also legal, but then the values ​​are undefined. However, you guarantee that using an unqualified char keep the value (therefore bare char cannot have traps or padding bits), according to 3.9p2:

For any object (except the subobject of the base class) of the trivially copied type T, regardless of whether the object has a valid value of type T , the basic bytes (1.7) that make up the object can be copied to a char or unsigned char array. If the contents of a char or unsigned char array are copied back to the object, the object must retain the original value.

("indefinite" values ​​are slightly weaker than "implementation-defined" values ​​- the semantics are the same, but the platform is not required to document what values ​​are.)

+3
source

The language does not say that this happens immediately after undefined behavior. He simply says that the representation c[0] may turn out to be an invalid (trap) representation, in which case the behavior is really undefined. But in cases where c[0] not a trap representation, the behavior is determined by the implementation.

If you use an unsigned char array, trap representation becomes impossible and the behavior becomes a purely defined implementation.

+6
source

This is a clearly implemented behavior.

The internal representation of int is not defined by the standard (implementations can choose small or large endian or something else), so it cannot be a clearly defined behavior: the result can be different on different architectures.

In a certain system (the architecture and the C compiler and (ultimately) the configuration), the behavior is completely defined: on the big endian you get 1, on the small endian a 0. Thus, this is the behavior determined by the implementation.

+1
source

Source: https://habr.com/ru/post/984062/


All Articles