4

Does the following scenario have undefined behavior?

void do_stuff(const int *const_pointer, int *pointer) {
    printf("%i\n", *const_pointer);
    *pointer = 1;
}

int data = 0;
do_stuff(&data, &data);

If this is undefined behavior it could probably cause problems if the compiler assumes that the value that const_pointer points to never changes. In this case it might reorder both instructions in do_stuff and thereby change the behavior from the intended printf("0") to printf("1").

alk
  • 69,737
  • 10
  • 105
  • 255
FSMaxB
  • 2,280
  • 3
  • 22
  • 41
  • 2
    No. `const` doesn't work this way. It would be worse than utterly useless if it did. `const` on a pointer means that an object cannot be changed *through this pointer*, not that it cannot be changed at all. – n. m. could be an AI Jun 26 '16 at 09:46
  • @n.m. It would sometimes be useful to have a way of telling the compiler "I promise that the data pointed to by the pointer has been initialised and won't ever be modified again", for instance when the same expression is calculated multiple times in a function, and the compiler can make sure it's only calculated once if the expression's inputs are truly constant. While you're right that `const` doesn't work this way, I don't think it would be "worse than utterly useless" if it did. –  Jun 26 '16 at 09:56
  • 2
    @hvd: That's what `restrict` in C99 is for. It is not exactly that (the concept is more general), but in combination with `const` it is intended to have this effect as well. – AnT stands with Russia Jun 26 '16 at 09:58
  • @hvd: Yes, that's what I mean by the concept being more general. `restrict` does not say that the pointed object is non-modifiable. Instead, it helps to compiler to determine whether the pointer object (possibly modifiable) is actually modified by some stretch of code. It should help the compiler to optimize the code regardless of whether there's a `const` there or not. I'd say it achieves the same effect as the suggested "hard const", but in a more general way. – AnT stands with Russia Jun 26 '16 at 10:06
  • @hvd Perhaps it could be useful, but I have no idea how to make such modifier work in C. For ex. `void foo(hardconst int* p);` Can you call this function: `int a = 2; foo(&a);` and then still be able to modify `a`? – n. m. could be an AI Jun 26 '16 at 10:51
  • @hvd The hint is: use a local variable that stores *p before the first comparison. – 2501 Jun 26 '16 at 10:52
  • @hvd What about storing a hardconst pointer in a heap-allocated data structure? – n. m. could be an AI Jun 26 '16 at 10:56
  • 1
    @hvd Apparently restrict + const you can tell the compiler the object won't be modified: http://stackoverflow.com/a/28800332/4082723 – 2501 Jun 26 '16 at 10:58
  • @2501 Huh. I stand corrected. Will clean up some of my comments here, looks like `restrict` in combination with `const` does achieve exactly what I thought it wouldn't, and what the OP thought `const` by itself might do. Good to know! –  Jun 26 '16 at 11:00
  • @hvd The compiler can only change it back to *p if it can prove the result of the execution is the same as if you used the local. Since the local won't be changed, (we guarantee no address taken and no changes of it), then both if statement will have the same outcome. – 2501 Jun 26 '16 at 11:01

2 Answers2

2

If the compiler can prove that the value pointer to by a pointer to const will not change then it will not need to reload the value, or keep the ordering.

In this case this cannot be done because the two pointers may alias, so the compiler cannot assume the pointers don't point to the same object. (The call to the function might be done from a different translation unit, the compiler doesn't know what is passed to the function.)

There is no undefined behavior in your example, and you are guaranteed that the printf will output 0.

2501
  • 25,460
  • 4
  • 47
  • 87
0

A const_pointer merely means that the data it points to cannot be changed.

When you pass a pointer to your function, it's entirely up to you to decide whether it should be const or not. const is a protection tool for you to prevent unwanted changes to your data. But without const, a function can still work. For example, your own version of strcpy can be written either as :

strcpy( char *s, const char *t );

or,

strcpy( char *s, char *t ); // without const, still work, just not as good as the first version

So there shouldn't anything unexpected in your code: you cannot modify data via const_pointer, but you can modify it via pointer (even when the two pointers are pointing to the same location).

artm
  • 17,291
  • 6
  • 38
  • 54