views:

175

answers:

6

Take this piece of code:

int a;
int *pointer = &a;

int **b = &(&(*pointer));

Would the above set b to the address of pointer or not?

The reason I ask is because *pointer gives the value of a, and the reference of that is the address of a. Is this treated as just the address of a, or is it also treated as pointer.

Does this make sense? Could I do:

&(*pointer) = a;
+6  A: 

No. In C, you can only get a pointer to a storage area (which means a variable, an array element, or another pointer; they call those "l-values"), not to any expression. You cannot get a pointer to an expressions that has no defined storage area (like an addition, or the result of a function call). It should be noted however that C++ messes these rules with references, but for the sake of clarity, I'll leave it out.

Pointers aren't magical: in the end, they're just integers. Therefore, when you get the pointer of a pointer, it's just like you were getting the pointer of an integer. It has no more repercussions.

For instance, if you get the pointer to a in your code, you're just copying this address in another variable. Nothing keeps you from changing said variable:

int a;
int* p = &a;
p = NULL;

And doing this, you a will remain unaltered. All you can change about a is its value. Its address is immutable. Anything else would imply that &a = NULL (or any other pointer value) would work, which doesn't.

zneak
Alexander Rafferty
zneak
"If you can't do it, then you can't get a pointer to it." is wrong. Arrays and const variables are a couple exceptions.
R..
@R.. Yeah, I removed that part.
zneak
+1  A: 

You can't take the address of something twice, so the above code probably won't even compile (have you tried that? What happened?).

Greg Hewgill
When I tried it, gcc says `warning: argument to ' this will be a hard error in the future` but `**b` gives the value of `a`.
jleedev
@jleedev: It should be a compiling error.
Brian R. Bondy
@jleedev: That sounds like you have a pretty old version of gcc. What are you using?
Greg Hewgill
jleedev
+3  A: 

int **b = &(&(*pointer));

This doesn't, or shouldn't compile.

You can only take the address of an l-value. (See below for a description)

C++03 S5.3.1-2:

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualifiedid. In the first case, if the type of the expression is “T,” the type of the result is “pointer to T.” In particular, the address of an object of type “cv T” is “pointer to cv T,” with the same cv-qualifiers. For a qualified-id, if the member is a static member of type “T”, the type of the result is plain “pointer to T.” If the member is a nonstatic member of class C of type T, the type of the result is “pointer to member of class C of type


...and the reference of that is the address of a...

Also you are using the term reference wrong here. & is a symbol that is used for different things. one of those things is to declare references, an unrelated thing is the address of unary operator. The later is not called a reference.


Does this make sense? Could I do: &(*pointer) = a;

An address of a variable, and hence &(*pointer) or equivalently &a are r-values.

You can't assign anything to an r-avlue. Ignoring things like const you can consider an r-value something that must appear on the right hand side. An l-value is kind of like left hand side but really it means it can be stored in a storage location (the difference is because a const object for example can't appear on the left hand side but it is still considered an l-value).

Brian R. Bondy
A: 

In your expression:

*ptr is a lvalue &(*ptr) is a rvalue

&(&(*ptr)) is an ill-formed expression as you are trying to take the address of an rvalue which is not allowed in C++.

Furthermore,

&(*pointer) = a;

is ill-formed, because the type of the lhs expression is 'int *' where type of rhs expression is 'int'. C++ does not allow converting an 'int' to 'int *'

Chubsdad
A: 

Would the above set b to the address of pointer or not?

No, it won't. &(*pointer) is the address of a, which is just a number (an r-value), and you can't take the address of or assign to an r-value. So both &(&(*pointer)) and &(*pointer) = a will not compile.

The address of pointer is simply &pointer, so what will work is int **b = &pointer;.

casablanca
A: 

1.No, and that make compile error at int **b = &(&(*pointer));
2.Set b to the address of pointer: int **b = &pointer;
3.&(*pointer) = a; -> NO you cant. &something is constant cant be changed, must be *pointer = a; or pointer = &a;

pinichi