B
Ben Bacarisse
Tim Rentsch said:Ben Bacarisse said:Richard Damon said:On 2/1/13 5:41 AM, BartC wrote:
The sizeof operator can be defined in a way that satisfies all
the Standard's requirements but still allows this example to
allocate only 100 nibbles.
So what would be the value of sizeof(*x)? It can only really
be 1 or 0. [snip elaboration]
Actually that isn't right. Using 'sizeof' on a non-standard
datatype may behave in unexpected ways. Here's a hint: sizeof
yields a result of type size_t; size_t is an (unsigned) integer
type; integer types larger than character types may have padding
bits. Can you fill in the rest?
What, that extra information is stored in those padding bits? How is
that going to help?
What bit-pattern could be returned by sizeof(*x) that would make
100*sizeof(*x) yield 50 instead of 100?
one simple solution is to have the sizeof operator not return a size_t
for the nybble type, but some special type that does math "funny" to get
the right value, for example a fixed point type with 1 fractional bit.
When doing arithmetic on this type, the compiler can get the "right"
answer, and also do the right thing when converting it to a standard
type.
I don't see how that can be permitted, at least without twisting
things some more! The type of a sizeof expression is size_t (an
unsigned integer type) and the result must be "an integer".
Here's another way of looking at it that may help. Using sizeof
is supposed to give the size of its operand in bytes. For a
four-bit data type, that should be a number strictly between
zero and one. Under 6.5 p5, such a circumstance qualifies as an
exceptional condition and therefore is undefined behavior.
[The thread has become split and I don't want to say essentially the
same things in two places so I'll just reply here.]
The source of the UB is immaterial to my complaint, which should really
be directed at myself: I should have known better! Given the nature of
UB, the first part of your teaser:
"The sizeof operator can be defined in a way that satisfies all the
Standard's requirements"
is essentially meaningless. Of course we can satisfy all the standard
requirements for undefined behaviour -- there are none!
I thought you meant more than that. I thought you meant more than "it
can be made to work".
I was meaning to say something stronger, or at least how I think
of it is stronger.
Yes, I know. But to be clear my remark was to Richard Damon who might
have been suggesting (I was not sure -- hence the interrogative) a more
global kind of undefined behaviour as a way of dealing with what he saw
as a problematic case (the two examples above). It seems from other
posts that he was not going there, but was,like you, imagining a more
localised UB.
There is local undefined behavior at sizeof,
because of the exceptional condition, and another local undefined
behavior for a size_t with non-zero fraction bits. However, once
these two local undefined behaviors are defined, everything else
proceeds definedly (not counting things like pointers to the new
type, etc, which also have to be defined, but I think you get the
idea). The presence of undefined behavior is repaired purely
locally by defining the semantics for these two specific cases, and
otherwise has no effect (again assuming that other aspects have
been defined suitably).
Absolutely. I saw no problem with making it work, and having extra bits
available allows the problem of returning a non-standard value to be
contained, as it were. (My thought was to imagine a type-tagged memory
architecture which is just fancy padding bits by another name.)