Chris Robinson skrev:
On Tuesday 22 September 2009 12:32:35 am Mike Kaplinskiy wrote:
It actually does not dereference anything.
Does the C standard specify that taking the address of a struct member being dereferenced doesn't actually cause a dereference, instead just offsetting?
It doesn't specify that * causes a dereference as such. It's known as the "indirection" operator (not the "dereference" operator), and if its operand is a pointer, it "returns" the object pointed to, as a lvalue, which is no more a dereference than any other expression. Only evaluating or assigning to this lvalue would cause an actual access (or dereference).
In other words, just like &some_var will not actually access some_var, &(*ptr_var) will not actually dereference ptr_var. (There'd be no point in doing that.)
Doing foo-> is identical to (*foo)., so dmW->dmFormName is the same as &(*dmW).dmFormName, which does technically cause a dereference, followed by taking the address of the field.
I doubt that'd even be possible. Dereferencing an address would take the data at that address, and you can't relate that data back to an address. Hence, the only sane way to take an address is to not dereference it first. (And what would the dereference be for? On most architectures I know, there's no way to tell the CPU to access memory without either reading or writing that memory location, and this code does neither.)
However, since GCC will remove deadcode and it's simple to see the dereference isn't needed, it just optimizes it away. I wouldn't even be surprised if this behavior is guaranteed by GCC with no optimizations enabled.. but I'm not so sure that it's guaranteed by the C standard. Is it?
I'm not sure, but I haven't heard about any "please try to emit meaningless code for no reason" section, so this kind of construct is a generally safe, and very, *very* widespread, practice.