Re: Just want to clarify the whole "char" thing
Frederick Gotham wrote:
I realise that none of the following types may contain padding bits, and
that all of their bits must take part in value representation:
signed char
unsigned char
(As "char" must map to one of the above, this also applies to "char".)
What I would like to clarify however, is the possiblity of a "signed char"
(and thus plain char) having an invalid value, or "trap value".
Below, I reproduce code which prints out an object's bytes by using an
"unsigned char". If I were to change it to "signed char" or plain char,
could the code potentially invoke undefined behaviour?
#include <ostream>
template<class T>
void PrintObjectBytes(T const &obj,std::ostream &os)
{
unsigned char const * const p_over =
reinterpret_cast<unsigned char const *>(&obj + 1);
unsigned char const *p =
reinterpret_cast<unsigned char const *>(&obj);
do os << (unsigned)*p++ << " ";
while(p != p_over);
os << '\n';
}
#include <iostream>
#include <vector>
int main()
{
std::vector<double> obj1;
int obj2[5] = {2,3,4,5,6};
PrintObjectBytes(obj1, std::cout);
PrintObjectBytes(obj2, std::cout);
}
Using "signed char" leads to UB : Even if the value-representation
would be ok.
Because the compiler may assume that a signed char can't be an alias of
a non-char type.
The revelant paragraph is 3.10-15 [basic.lval]
"15If a program attempts to access the stored value of an object
through
an lvalue of other than one of the following types the behavior
is
undefined25):
_________________________
25) The intent of this list is to specify those circumstances in
which
--the dynamic type of the object,
--a cv-qualified version of the dynamic type of the object,
--a type that is the signed or unsigned type corresponding to
the
dynamic type of the object,
--a type that is the signed or unsigned type corresponding to a
cv-
qualified version of the dynamic type of the object,
--an aggregate or union type that includes one of the
aforementioned
types among its members (including, recursively, a member of a
sub-
aggregate or contained union),
--a type that is a (possibly cv-qualified) base class type of
the
dynamic type of the object,
--a char or unsigned char type.
_________________________
an object may or may not be aliased."
For unsigned char or char, I tend to think that it's ok, even though
4.1 [conv.lval] seems to say that it has UB.
"
If the object to which
the lvalue refers is not an object of type T and is not an object of
a
type derived from T, or if the object is uninitialized, a program
that
necessitates this conversion has undefined behavior.
"
Actually, 4.1 is not clear since it doesn't say what means the *object
to which the lvalue refers*. Is it the dynamic type of the object? Is
it any type through which 3.10-15 says that the object can be accessed?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]