4

Ok, recently I was surprised by this state of affairs: Evaluating the condition containing unitialized pointer - UB, but can it crash?

Seems this:

int *p;
if(p != NULL)
{
  int k;
}

can theoretically already crash.

My question is: when is it safe to check value of a pointer? When is it safe to make a check: if(ptr == SomeValue) - so that it does not trigger UB?

Community
  • 1
  • 1
  • You probably already know this, but to nitpick a bit: It's not just about crashing. Since it's undefined behavior, _anything_ can happen. – Thomas Padron-McCarthy Mar 18 '14 at 07:01
  • @ThomasPadron-McCarthy: yes, so it's Bad in any case - so it seems I must *always* initialize variables before use in C. –  Mar 18 '14 at 07:13
  • A typical example of how this could crash etc. would be if your hardware prevents an address register being loaded with an address that doesn't exist. – M.M Mar 18 '14 at 08:35
  • @dmcr_code: Well, yes, you should always initialize variables before use in C, but the main reason for that is not that it might cause strange problems on some strange hardware somewhere. Instead, I would say that the main reason is that on normal hardware today, in your example you have no idea if **p** contains NULL or not. – Thomas Padron-McCarthy Mar 18 '14 at 10:02

1 Answers1

6

It is only safe to check the value of an initialized automatic variable. Pointers are no exception.

This is spelled out in §6.3.2.1¶2 in C.11:

Except when it is the operand of the sizeof operator, the unary & operator, the ++ operator, the -- operator, or the left operand of the . operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue); this is called lvalue conversion. ... If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.

jxh
  • 69,070
  • 8
  • 110
  • 193
  • So if I rewrite my code like this: `int *p=0; if(p != NULL) { int k; }` I am safe (at least to make that check)?? –  Mar 18 '14 at 06:44
  • 1
    Yes...if you initialize the pointer first, the check is safe. – Jonathan Leffler Mar 18 '14 at 06:46
  • How do you write those pretty paragraph and section symbols? – ajay Mar 18 '14 at 07:46
  • I always like answers which quote the standard. Makes it definitive :) – ajay Mar 18 '14 at 07:48
  • @ajay: I use HTML codes when typing in answers. I don't know what I need to hit on my keyboard to make them appear, so in comments like this, I would cut+paste. – jxh Mar 18 '14 at 18:22