It seems unclear, but there are claims that dereferencing a nullpointer is undefined behavior:
A comment by M.M.
This note was in fact removed as the result of DR 1102 with the stated reasoning being that it was not undefined behaviour to dereference a null pointer.
indicates that it might be defined behavior.
General agreement seems to be that it is undefined behavior.
So. Is it fine to call cv::setBreakOnError(true)
, which is supposed to cause raising an Access Violation on error()
? Its implementation is as follows:
if(breakOnError)
{
static volatile int* p = 0;
*p = 0;
}
Or does calling this function mean, that due to undefined behavior, anything could now happen when my program is compiled and run?
My own best guess is that it is technically undefined but happens to always(?) do the right thing on windows and linux
It seems unclear, but there are claims that dereferencing a nullpointer is undefined behavior:
A comment by M.M.
This note was in fact removed as the result of DR 1102 with the stated reasoning being that it was not undefined behaviour to dereference a null pointer.
indicates that it might be defined behavior.
General agreement seems to be that it is undefined behavior.
So. Is it fine to call cv::setBreakOnError(true)
, which is supposed to cause raising an Access Violation on error()
? Its implementation is as follows:
if(breakOnError)
{
static volatile int* p = 0;
*p = 0;
}
Or does calling this function mean, that due to undefined behavior, anything could now happen when my program is compiled and run?
My own best guess is that it is technically undefined but happens to always(?) do the right thing on windows and linux
Share Improve this question edited Mar 4 at 23:55 Christoph Rackwitz 15.9k5 gold badges39 silver badges51 bronze badges asked Mar 4 at 12:39 lucidbrotlucidbrot 6,3013 gold badges47 silver badges72 bronze badges 11 | Show 6 more comments2 Answers
Reset to default 8The reason dereferencing a null pointer value is said not to be undefined is they are using “dereferenced” to mean the *
operator is applied to the pointer, not that there is actually an attempt to access a pointed-to-object.
The DR 1102 you link to further links to issue 232, where we can see one of the examples given is typeid(*p)
. Evaluation of this when *p
is a polymorphic class type is defined to throw the exception bad_typeid
. That is a definition of behavior, so the behavior is not undefined.
Actually attempting to access the dereferenced pointer would be undefined; foo = *p
or *p = 0
would be undefined.
Edit: according to Eric in the comments it is still undefined behavior because dereferencing a nullptr
is different than accessing the underlying object, regardless of volatile
existence, the rest of the answer is my original (questionable) interpretation of the standard.
the main point here is that it is a pointer to a volatile
object, which is underspecified by the standard. it is up to the compiler how to implement it.
[decl.type.cv.5] The semantics of an access through a volatile glvalue are implementation-defined.
on systems with no memory protection (some embedded devices) you can write to address zero, and the system won't (immediately) crash.
you cannot use the standard to reason about this code, only the compiler/OS docs. and it seems to work fine on the target OS/compilers, which is the whole reason why volatile
is underspecified by the standard.
If the pointer wasn't to a volatile
then it would be undefined behavior, and the compiler would be allowed to do anything, including removing this memory access, or breaking the code before it.
std::breakpoint
(C++26 onward), orboost::debug::debugger_break
. – Eljay Commented Mar 4 at 13:50&*p
(wherep
has a null pointer value) is not undefined because it does not actually fetch from memory ortypeid(*p)
, which is defined to throw an exception. So it is not merely having the lvalue*p
in an expression that is undefined, and hence merely notionally dereferencing the null pointer value is not undefined. However, actually dereferencing the value in the sense many people might think, turning the pointer into a value (lvalue-to-rvalue conversion), is undefined. – Eric Postpischil Commented Mar 5 at 0:48