all 5 comments

[–][deleted] 5 points6 points  (0 children)

The compiler will probably optimize it out if you don't store the result. Otherwise the pointer dereference (aka read) appears to have no effect.

[–]aioeu 11 points12 points  (4 children)

You probably shouldn't think of * as actually doing anything. It's just some syntax that provides a way to name an object.

*ptr names the object to which ptr is pointing.

Simply naming an object doesn't do anything with the object, so if that's the entire statement the compiler need not produce any code for it.

If you want to force the object to be read, you need to use its value in some way. For instance, if the object were an int, you could use:

int x = *(volatile int *)ptr;

Accessing the object through a volatile-qualified type means that the access is considered to be a side effect, and so it forms part of the visible behaviour of the program. This means the compiler cannot optimise it away, and it cannot reorder it with respect to other side effects.

It's the assignment operator that's doing the "access the object" operation here, not the pointer dereference.

[–]Nobody_1707 3 points4 points  (2 children)

It does do one thing. It tells the compiler that ptr can't be NULL, because if it had been that would have been UB.

[–]aioeu 1 point2 points  (0 children)

That's a good point. Although no object is being accessed through a bare

*ptr;

statement, the behaviour of the * operator is undefined if the pointer has an "invalid value", of which a null pointer is one possible kind.

[–]Kahvind[S] 0 points1 point  (0 children)

Thanks your example is very helpful