Reputation: 361
I am a C++ noob and I am quite sure this is a stupid question, but I just do not quite understand why an error arises (does not arise) from the following code:
#include <iostream>
using namespace std;
int main()
{
int a,*test;
*test = &a; // this error is clear to me, since an address cannot be
// asigned to an integer
*(test = &a); // this works, which is also clear
return 0;
}
But why does this work too?
#include <iostream>
using namespace std;
int main()
{
int a, *test= &a; // Why no error here?, is this to be read as:
// *(test=&a),too? If this is the case, why is the
// priority of * here lower than in the code above?
return 0;
}
Upvotes: 17
Views: 1138
Reputation: 8239
You are actually doing an initialisation like this in first case,
int *test = &a;
It means that, you are initialising a pointer for which you mention *
to tell the compiler that its a pointer.
But after initialisation doing a *test
(with an asterisk) means that you are trying to access the value at the address assigned to pointer test
.
In other words, doing an *test
means you are getting the value of a
because address of a
is stored into pointer test
which is done by just doing a &a
.
&
is the operator to get the address of any variable. And *
is the operator to get the value at address.
So initialisation & assignment are inferred differently by the compiler even if the asterisk *
is present in both the cases.
Upvotes: 2
Reputation: 1133
There's a subtle difference there.
When you declare int a, *test, you're saying "declare a as an integer, and declare test as a pointer to an integer, with both of them uninitialized."
In your first example, you set *test to &a right after the declarations. That translates to: "Set the integer that test points to (the memory address) to the address of a." That will almost certainly crash because test wasn't initialized, so it would either be a null pointer or gibberish.
In the other example, int a, *test= &a translates to: "declare a as an uninitialized integer, and declare test as a pointer initialized to the address of a." That's valid. More verbosely, it translates to:
int a, *test;
test = &a;
Upvotes: 0
Reputation: 16156
The fundamental difference between those two lines
*test= &a; // 1
int a, *test= &a; // 2
is that the first is an expression, consisting of operator calls with the known precedence rules:
operator=
/\
/ \
/ \
operator* operator&
| |
test a
whereas the second is a variable declaration and initialization, and equivalent to the declaration of int a;
followed by:
int* test = &a
// ^^ ^^ ^^
//type variable expression giving
// name initial value
Neither operator*
nor operator=
is even used in the second line.
The meaning of the tokens *
and =
(and &
as well as ,
) is dependent on the context in which they appear: inside of an expression they stand for the corresponding operators, but in a declaration *
usually appears as part of the type (meaning "pointer to") and =
is used to mark the beginning of the (copy) initialization expression (,
separates multiple declarations, &
as "reference to" is also part of the type).
Upvotes: 30
Reputation: 37520
You just hit two of the horrible language design spots: squeezing declarations into one line and reuse of *
symbol for unrelated purposes. In this case *
is used to declare a pointer (when it is used as part of type signature int a,*test;
) and to deference a pointer (when it is used as a statement *test = &a;
). The good practice would be to declare variables one at a time, to use automatic type deduction instead of type copypasting and to use dedicated addressof
method:
#include <memory> // for std::addressof
int a{};
auto const p_a{::std::addressof(a)};
Upvotes: 1
Reputation: 21
You're confusing two uses for *.
In your first example, you're using it to dereference a pointer. In the second example, you're using it to declare a "pointer to int".
So, when you use * in a declaration, it's there to say that you're declaring a pointer.
Upvotes: 2
Reputation: 17483
int a, *test= &a;
is equivalent of:
int a;
int* test = &a;
and perfectly valid as you initialize test
which has a type of pointer to int with an address of variable a
which has a type of int.
Upvotes: 3