2

The following code is undefined behavior in C++ (although it will work okay on almost any widely used implementation):

int* pointer; //uninitialized - likely illegal pointer value
pointer++; //incrementing an illegal pointer is UB

Is the above code legal in C?

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • 1
    Btw, legal or not, what do you hope to achieve with it - I mean, is there any valid usecase if it was legal? – Amarghosh Nov 02 '10 at 10:36
  • 1
    @Amarghosh: Easy - for example, you write a memory manager that calls `free()` and then prints "block at address X freed". Passing the pointer value into `printf()` after calling `free()` on that pointer turns out to be UB. – sharptooth Nov 02 '10 at 10:55
  • 4
    presumably you could get away with that in C99 without causing undefined behavior by copying the pointer address into a `intptr_t` before calling `free()`, and then passing the `intptr_t` to `printf` after the actual pointer is freed. – Charles Salvia Nov 02 '10 at 11:07
  • @Charles Salvia: Yes, that's the way to do that. – sharptooth Nov 02 '10 at 11:24

3 Answers3

8

It's undefined behavior in C as well because on certain architectures, loading an invalid pointer into a register triggers a hardware fault.

See Is storing an invalid pointer automatically undefined behavior?

Community
  • 1
  • 1
Charles Salvia
  • 52,325
  • 13
  • 128
  • 140
  • This is crazy! Damn standard, I think I'll never obey it. Please tell me then, what if I have a `union` which consists of a pointer and an integer? – valdo Nov 02 '10 at 12:25
  • Next you'll say a value of type `char` will trigger hw fault if the character is unreadable! – valdo Nov 02 '10 at 12:25
  • BTW there exist a lot of algorithms that iterate through an array, whereas they actually increment the element pointer **before** checking for loop break condition. That is, they increment the pointer, but not necessarily dereference it. Are you saying this is a potenrial crash? – valdo Nov 02 '10 at 12:43
  • @valdo: That is also undefined, and whether it will work or not in practice depends entirely on the type of integer and whether it can hold the bits of a pointer. But there is absolutely, positively no reason to use a union to get the integer value of a pointer when `intptr_t` exists. – Steve M Nov 02 '10 at 12:43
  • I like to think that a pointer is an integer, as long as you don't actually dereference it. And I don't care what standard actually says about it, please forgive me Kernigan & Richie. – valdo Nov 02 '10 at 12:44
  • @valdo #2: Sure, if incrementing it puts it greater than 1 element beyond the end of the array. – Steve M Nov 02 '10 at 12:47
  • @Steve M: The existence of `intptr_t` doesn't matter. I may want to have a `union` of a pointer and a `struct` consisting of a `short` and two `char`s. The point is that I **really want** to think that my pointer is just another variable. Wether I want to dereference it or directly look at its value should be my decision only. – valdo Nov 02 '10 at 12:47
  • @Steve M: Alright, let's agree on this. However I wonder how the compiler will handle the situation that I described: a `union` of a pointer and something else. Will this prevent it from loading the pointer value into the so-called "pointer register" unless it's actually dereferenced? – valdo Nov 02 '10 at 12:52
  • @Steve M: In other words - the compiler will have to generated different code since it'll know that my pointer **may** actually hold an invalid pointer value. It's a pity, since C language (in contrast to C++) should be very transparent. – valdo Nov 02 '10 at 12:54
1

It is undefined behavior in C99. The value of pointer is "indeterminate" (6.7.8.10) and an indeterminate value can be a trap value that causes undefinedness when used.

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
1

Not legal. Code like this will compile, but with warnings. Don't ignore them. Don't write code like this. It can affect your system in many not so nice ways. My university teacher once told us he managed to erase one machine's BIOS using code with undefined behaviour.

darioo
  • 46,442
  • 10
  • 75
  • 103