Lawrence said:
S.Tobias wrote:
I don't understand.
Where exactly is it written that `size_t' must
be able to cover sizes of all types?
All I can find is that `size_t'
is the type returned by `sizeof' operator. Does it mean that
implementations must forbid types whose size cannot be taken?
N869
6.5.3.4 The sizeof operator
[#2] The sizeof operator yields
the size (in bytes) of its
operand, which may be an expression or the
parenthesized
name of a type
If the size cannot be taken, then how can sizeof do
what it's supposed to do?
It can't which means that the compiler
should not successfully translate
the program, which is fine.
So what should a compiler do? Should it reject the code which
contains a declaration of type that is too large, or is it UB
applying `sizeof' to such type?
It takes the 3rd option:
"I accept your code but I can't translate it".
What does "accept" mean?
I don't know that "accept" means
"be able to successfully translate and execute",
but I can't think of what else it could mean.
Well undefined behaviour can occur as
a lack of definition of behaviour,
but I don't think that's a valid argument here.
If it cannot generate code that conforms to the standard's
specificaton then it must not generate code.
Beyond generating code,
I can't apply meaning to what sizeof is supposed to do.
sizeof returns the size of the type of its operand. If it cannot
successfully evaluate to a value that meets the requirements of the
standard then it mut nut successfully evaluate.
Actually my statement the the compiler must not generate code is too
strong, the compiler can generate code but the code must not complete
such a sizeof operation successfully.
When the operand is a type with (1 + (size_t)-1) bytes.
what should sizeof return?
That's the point, it cannot produce a result without violating the
standard so it must not produce a result.
I can't answer that question in English. It's not just a matter of
generating code.
It is a matter of implementing the semantics specified by the standard.
It is clear that in this case those semantic cannot be implemented, well
before generating code is an issue.
There is a defect in the standard in as much as it should state that the
size of a declared object shall not exceed SIZE_MAX. That would allow
undefined behavour. However as things stand there is no opportunity for
undefined behaviour because the behaviour of sizeof is clearly defined. It
just happens to be unimplementable in this case which is a clear defect.
If a program defines two objects
or an object with more than 65535 bytes, then it is beyond what 5.2.4.1
says
an implementation shall be able to translate and execute.
It is certainly more than is required for the one program that the
implementation must be able to translate and execute successfully. However
that doesn't stop it being a strictly conforming program.
I think the "one" reference is saying that if something can translate
and execute any strictly conforming program then it's a conforming
implementation, and that if it can't, it isn't.
The text is pretty clear:
"The implementation shall be able to translate and execute at least one
program that contains at least one instance of every one of the following
limits."
It is a conformance requirement on the implementation. There must be at
least one program that the implementation can translate and execute and
that program must contain at least once instance of each of the specified
limits. There is nothing in the standard that requires that an
implementation be able to successfully translate and execute any other
program.
It is easy to construct strictly conforming programs for a compiler that
it can't translate and execute successfully, so the standard cannot
require an implementation to translate and execute every strictly
conforming program, if it is to be useful in the real world.
Lawrence