Re: Undefined behaviour with Non-static, non-polymorphic + null
pointer?
On Nov 21, 7:15 pm, Marco Manfredini <ok_nospam...@phoyd.net> wrote:
Victor Bazarov wrote:
(I mean, they could really make an appendix "Authoritative List of
UB's", because it's really a nuisance to find these only scattered
around in the Standard)
I am not sure how such a list would help. You would still have to
understand that the postfix expression (x->) dereferences the pointer
regardless what's following it. How would mentioning that if one
dereferences a null pointer it's UB help understanding that x->n
does in fact dereference 'x' (if 'n' is a static member)?
Well, for an example 5.2.5 just says that x->y is dereferenced
during evaluation. So glancing over the paragraph I might
remember that "dereference" can invoke UB, but what are the
details? If *what* is dereferenced?
The pointer. Dereferencing is a run-time action, the result of
the * operator.
And then there is sizeof (and soon decltype) which do not
evaluate their argument - so am I getting this right that
sizeof(x->y) should always be defined?
Yes. The standard explicitly says that the arguments to sizeof
are not evaluated. No run-time behavior.
I remember that there was a debate about that question some
time ago on clmc++.
So I think, that it would be nice, if an (effectual) Appendix
would turn the UBs inside out and list all UBs with pointers
back to the context of their premises,
There's not much to say about pointers: dereferencing a null
pointer, or a pointer to one past the end of an array, is
undefined behavior (in C++---in C, there are certain special
cases where one past the end of an array is allowed).
like:
Dereferencing
If t is of pointer type T and *t(1) is evaluated(2) and t does not point
to an object of type T (3), it's UB
(1) When is *t implicitely formed?: see "->"
Implicit or explicit has nothing to do with it. If the standard
says (and it does) that p->f() has the semantics of (*p).f(),
then it has the semantics of (*p).f(). I don't see what more
needs to be said.
(2) When is *t not evaluated? see: sizeof, decltype
Again, the standard is fairly explicit, although perhaps not
where you'd expect. =A73.2/1: "An expression is potentially
evaluated unless it is either the operand of the sizeof
operator, or the operand of the typeid operator and does not
designate an lvalue of polymorphic class type."
(3) How can t not point to an object of it's declared type:
see union, reinterpret_cast, null pointer etc..
A pointer value can be considered as having one of four
categories:
-- it points to an object (no problem there),
-- it points to one past the end of an array (dereference
illegal, but pointer arithmetic still allowed).
-- it is null (no dereference, and I think, no pointer
arithmetic---but I'm not sure about p+0), and
-- anything else (nothing allowed, even lvalue to rvalue
conversion is undefined behavior)
With regards to unions, nothing changes. A union contains one
(and only one) of its members at a time. Any attempt to access
any other member is undefined behavior.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34