Reputation: 767
Below are the quotes from C99 6.2.6.1
- Values stored in non-bit-field objects of any other object type consist of n × CHAR_BIT bits, where n is the size of an object of that type, in bytes. The value may be copied into an object of type unsigned char [ n ] (e.g., by memcpy); the resulting set of bytes is called the object representation of the value.
Q1. Does 6.2.6.1 p5 mean object representation is defined only when an objected is divided by char?(why should it be divided by char, rather than remaining itself?)
// illustrating for Q1
#include <string.h>
int main(void)
{
int var = 5; // var is not the object representation of itself
char arr[sizeof(int)];
memcpy(arr, &var, sizeof(int)); // arr is the object representation of var
}
- Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is read by an lvalue expression that does not have character type, the behavior is undefined. If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that does not have character type, the behavior is undefined. Such a representation is called a trap representation.
Q2. Why doesn't only character type cause undefined behavior when trap representation value is stored?(why is to read trap representation undefined behavior unless an object doesn't have character type?)
Q3. I guess generally we don't have to read trap representation. But if one try to read it, does 6.2.6.1 p6 mean any wider type(than char) should be copied in a char array as Q1 code example?
// illustrating for Q3
#include <stdio.h>
#include <string.h>
#define TRAPVAL 0x12345678 // assume 0x12345678 is trap representation to the type int
int main(void)
{
int var = TRAPVAL;
printf("var: %x\n", var); // undefined behavior
char arr[sizeof(int)];
memcpy(arr, &var, sizeof(int));
printf("var: ");
for (int i = 0; i < sizeof(int); i++)
printf("%hhx ", arr[i]); // well defined
}
Upvotes: 0
Views: 397
Reputation: 181909
Q1. Does 6.2.6.1 p5 mean object representation is defined only when an objected is divided by char?
No. It simply means that the object representation is a sequence of values of type unsigned char
.
(why should it be divided by char, rather than remaining itself?)
The size of char
(and of unsigned char
) is the unit in which object sizes are measured. unsigned char
has no padding bits, so all its bits are significant to its value. Thus values of type unsigned char
are the basic units of storage in C's model of memory.
Note also that there are ways to access the individual bytes of an object representation that do not require copying the representation to an array, but the language specification chooses this definition to avoid forming a set of circular definitions.
Q2. Why doesn't only character type cause undefined behavior when trap representation value is stored?(why is to read trap representation undefined behavior unless an object doesn't have character type?)
Trap representations are a characteristic of interpreting a byte sequence as a value of a particular type. I suspect what you're missing is that C doesn't offer many choices for how you read a given object's representation: roughly speaking, you can do it as an object of a compatible type or as a sequence of [signed
|unsigned
] char
.* Only the latter alternative does not attempt to interpret the representation in question as an object of a type for which it is a trap representation.
Q3. I guess generally we don't have to read trap representation. But if one try to read it, does 6.2.6.1 p6 mean any wider type(than char) should be copied in a char array as Q1 code example?
No. You can examine the bytes of an object's representation in place by taking the object's address, casting that to type unsigned char *
, and reading the bytes through the pointer:
my_type o;
/* ... assign a value to o ... */
unsigned char *p = &o;
for (size_t i = 0; i < sizeof o; i++) {
printf("%hhx", *p++);
}
Do also note, however, that the "assign a value to o
" part is tricky if the objective is to produce a trap representation in o
.
*You can also read an object's representation as part of the representation of an aggregate or union that contains the object as a member, but that is not what the specifications are talking about here.
Upvotes: 2