Operator Precedence in declaring more pointers in one instruction - c++

I would like to understand why do i have to add an asterisk before each identifier when declaring more pointers with the same datatype on the same row.
Here is where i read from
Another thing that may call your attention is the line:
int * p1, * p2;
This declares the two pointers used in the previous example. But notice that there is an asterisk (*) for each pointer, in order for both to have type int* (pointer to int). This is required due to the precedence rules. Note that if, instead, the code was:
int * p1, p2;
p1 would indeed be of type int*, but p2 would be of type int. Spaces do not matter at all for this purpose. But anyway, simply remembering to put one asterisk per pointer is enough for most pointer users interested in declaring multiple pointers per statement. Or even better: use a different statement for each variable.
The operator precedence
The question: What rule is used here, what precedence is this? It is about comma or asterisk? I can't figure it out.

There is no any precedence rule. The gramma of a simple declaration looks like
decl-specifier-seq init-declarator-listopt ;
The sign * belongs to declarators not to decl-specidier-seq as for example type specifier int.
So you may for example rewrite the declaration
int * p1, * p2;
like
int ( * p1 ), ( * p2 );
where ( *p1 ) and ( *p2 ) are decalartors (thouhg in this case the parentheses are redundant)
You may not write for example
( int * ) p1, p2;
The compiler will issue an error.
Parentheses are required when a more complicated type is declared. For example let's declare a pointer to an array
int ( *p )[N];
where N is some constant.
So you may enclose declarators in parentheses.
Let's consider a more complicated declaration: of a function that returns a pointer to function and has as a parameter another function
void ( *f( int cmp( const void *, const void * ) )( int *a );
As for the precedence then rules of building declarators describe them in the gramma
For example
if you will write
int * a[10];
then it is an array of 10 elements of the type int *.
However if you will write
int ( *a[10] );
then its an array of 10 pointers to objects of the type int.
If you will write
int ( *a )[10];
then it is a pointer to an array of 10 integers.
Take into account that typedef is also a decl-specifier.
So for example this typedef
typedef int *intPtr;
you may rewrite like
int typedef *intPtr;
or even like
int typedef ( *intPtr );
One more example of declaration. Let's consider a multidimensional array. In can be declared like
int ( ( ( a )[N1] )[N2] );
though again the parentheses are redundant. However they can help to understand how arrays are implicitly converted to pointers to their first elements in expressions.
For example if you have an array
int a[N1][N2];
then to get a pointer declaration to its first element you can rewrite the declaration ,like
int ( a[N1] )[N2];
and now substitute a[N1] for *a (or for example *p).
int ( *p )[N2] = a;

There is not a precedence rule per se; rather, it is a rule that says that the int part applies to all the variables whereas the * only applies to the one right after it.
The general version of the rule is that all the specifiers in the declaration apply to every entity being declared. Specifiers include keywords like constexpr and static, as well as keywords that denote types like int and user-defined type names. The operators like * and & that modify the type specifiers to create more complex types, however, only apply to one entity at a time.

There's no operator precedence involved here. In fact there are no operators either. Operators operate on expressions, but this is a declaration.
The syntax for declarations is that:
T D1, D2, D3, D4;
means the same as:
T D1; T D2; T D3; T D4;
where:
T is declaration-specifier: no symbols, only keywords (e.g. int, const, static) and/or typedef-names.
Dn is a declarator, that is, an identifier (the name of the variable) perhaps with *, [] or (parameter-list) or grouping parentheses attached in various ways.
In your first example T is int, and the declarators are *p1 and *p2 .

Related

Why is the Dereference operator used to declare pointers?

Why is the * used to declare pointers?
It remove indirection, but doesn't remove any when you declare a pointer like int *a = &b, shouldn't it remove the indirection of &b?
Many symbols in C and C++ are overloaded. That is, their meanings depend on the context where they are used. For example, the symbol & can denote the address-of operator and the binary bitwise AND operator.
The symbol * used in a declaration denotes a pointer:
int b = 10;
int *a = &b,
but used in expressions, when applied to a variable of a pointer type, denotes the dereference operator, for example:
printf( "%d\n", *a );
It also can denote the multiplication operator, for example you can write:
printf( "%d\n", b ** a );
that is the same as
printf( "%d\n", b * *a );
Similarly, the pair of square braces can be used in a declaration of an array, like:
int a[10];
and as the subscript operator:
a[5] = 5;
Any time you have a pointer declaration with initialization like this:
type *x = expr;
it is equivalent to the separate initialization followed by assignment:
type *x;
x = expr;
It is not equivalent to
type *x;
*x = expr; /* WRONG */
It's part of the declaration, so it's not a dereference operator at all. Yet it still means the same thing.
int *a
can be read as
The value pointed by a is an int.
just like
printf("%d\n", *a);
can be read as
Print the value pointed by a.
See this answer to Correct way of declaring pointer variables in C/C++ for a bit on background on this.
Back when C was invented, a somewhat interesting choice was made. Variables would be declared in a kind of echo of how they would be used.
So
int a;
means "you can get an int out of a. Then,
int *a;
means you can get an int out of *a.
And,
int a[3];
means you can get an int out of a[index]; here, the size is put in where the index would be.
This can be chained to complex cases
int *a[3];
vs
int (*a)[3];
now if you don't know how C parsing works, this is opaque; but at least you only have to learn it once!
This is why some people think int* a is bad form, because the * is really attached to a not the int.
Initialization of the named variable is a different thing.
(some declaration) = (some expression)
the symbols in the declaration never act as expressions. They are the same symbols, just different meaning.

The difference between int* ptr; and int *ptr; C++ pointers [duplicate]

I've recently decided that I just have to finally learn C/C++, and there is one thing I do not really understand about pointers or more precisely, their definition.
How about these examples:
int* test;
int *test;
int * test;
int* test,test2;
int *test,test2;
int * test,test2;
Now, to my understanding, the first three cases are all doing the same: Test is not an int, but a pointer to one.
The second set of examples is a bit more tricky. In case 4, both test and test2 will be pointers to an int, whereas in case 5, only test is a pointer, whereas test2 is a "real" int. What about case 6? Same as case 5?
4, 5, and 6 are the same thing, only test is a pointer. If you want two pointers, you should use:
int *test, *test2;
Or, even better (to make everything clear):
int* test;
int* test2;
White space around asterisks have no significance. All three mean the same thing:
int* test;
int *test;
int * test;
The "int *var1, var2" is an evil syntax that is just meant to confuse people and should be avoided. It expands to:
int *var1;
int var2;
Many coding guidelines recommend that you only declare one variable per line. This avoids any confusion of the sort you had before asking this question. Most C++ programmers I've worked with seem to stick to this.
A bit of an aside I know, but something I found useful is to read declarations backwards.
int* test; // test is a pointer to an int
This starts to work very well, especially when you start declaring const pointers and it gets tricky to know whether it's the pointer that's const, or whether its the thing the pointer is pointing at that is const.
int* const test; // test is a const pointer to an int
int const * test; // test is a pointer to a const int ... but many people write this as
const int * test; // test is a pointer to an int that's const
Use the "Clockwise Spiral Rule" to help parse C/C++ declarations;
There are three simple steps to follow:
Starting with the unknown element, move in a spiral/clockwise
direction; when encountering the following elements replace them with
the corresponding english statements:
[X] or []: Array X size of... or Array undefined size of...
(type1, type2): function passing type1 and type2 returning...
*: pointer(s) to...
Keep doing this in a spiral/clockwise direction until all tokens have been covered.
Always resolve anything in parenthesis first!
Also, declarations should be in separate statements when possible (which is true the vast majority of times).
There are three pieces to this puzzle.
The first piece is that whitespace in C and C++ is normally not significant beyond separating adjacent tokens that are otherwise indistinguishable.
During the preprocessing stage, the source text is broken up into a sequence of tokens - identifiers, punctuators, numeric literals, string literals, etc. That sequence of tokens is later analyzed for syntax and meaning. The tokenizer is "greedy" and will build the longest valid token that's possible. If you write something like
inttest;
the tokenizer only sees two tokens - the identifier inttest followed by the punctuator ;. It doesn't recognize int as a separate keyword at this stage (that happens later in the process). So, for the line to be read as a declaration of an integer named test, we have to use whitespace to separate the identifier tokens:
int test;
The * character is not part of any identifier; it's a separate token (punctuator) on its own. So if you write
int*test;
the compiler sees 4 separate tokens - int, *, test, and ;. Thus, whitespace is not significant in pointer declarations, and all of
int *test;
int* test;
int*test;
int * test;
are interpreted the same way.
The second piece to the puzzle is how declarations actually work in C and C++1. Declarations are broken up into two main pieces - a sequence of declaration specifiers (storage class specifiers, type specifiers, type qualifiers, etc.) followed by a comma-separated list of (possibly initialized) declarators. In the declaration
unsigned long int a[10]={0}, *p=NULL, f(void);
the declaration specifiers are unsigned long int and the declarators are a[10]={0}, *p=NULL, and f(void). The declarator introduces the name of the thing being declared (a, p, and f) along with information about that thing's array-ness, pointer-ness, and function-ness. A declarator may also have an associated initializer.
The type of a is "10-element array of unsigned long int". That type is fully specified by the combination of the declaration specifiers and the declarator, and the initial value is specified with the initializer ={0}. Similarly, the type of p is "pointer to unsigned long int", and again that type is specified by the combination of the declaration specifiers and the declarator, and is initialized to NULL. And the type of f is "function returning unsigned long int" by the same reasoning.
This is key - there is no "pointer-to" type specifier, just like there is no "array-of" type specifier, just like there is no "function-returning" type specifier. We can't declare an array as
int[10] a;
because the operand of the [] operator is a, not int. Similarly, in the declaration
int* p;
the operand of * is p, not int. But because the indirection operator is unary and whitespace is not significant, the compiler won't complain if we write it this way. However, it is always interpreted as int (*p);.
Therefore, if you write
int* p, q;
the operand of * is p, so it will be interpreted as
int (*p), q;
Thus, all of
int *test1, test2;
int* test1, test2;
int * test1, test2;
do the same thing - in all three cases, test1 is the operand of * and thus has type "pointer to int", while test2 has type int.
Declarators can get arbitrarily complex. You can have arrays of pointers:
T *a[N];
you can have pointers to arrays:
T (*a)[N];
you can have functions returning pointers:
T *f(void);
you can have pointers to functions:
T (*f)(void);
you can have arrays of pointers to functions:
T (*a[N])(void);
you can have functions returning pointers to arrays:
T (*f(void))[N];
you can have functions returning pointers to arrays of pointers to functions returning pointers to T:
T *(*(*f(void))[N])(void); // yes, it's eye-stabby. Welcome to C and C++.
and then you have signal:
void (*signal(int, void (*)(int)))(int);
which reads as
signal -- signal
signal( ) -- is a function taking
signal( ) -- unnamed parameter
signal(int ) -- is an int
signal(int, ) -- unnamed parameter
signal(int, (*) ) -- is a pointer to
signal(int, (*)( )) -- a function taking
signal(int, (*)( )) -- unnamed parameter
signal(int, (*)(int)) -- is an int
signal(int, void (*)(int)) -- returning void
(*signal(int, void (*)(int))) -- returning a pointer to
(*signal(int, void (*)(int)))( ) -- a function taking
(*signal(int, void (*)(int)))( ) -- unnamed parameter
(*signal(int, void (*)(int)))(int) -- is an int
void (*signal(int, void (*)(int)))(int); -- returning void
and this just barely scratches the surface of what's possible. But notice that array-ness, pointer-ness, and function-ness are always part of the declarator, not the type specifier.
One thing to watch out for - const can modify both the pointer type and the pointed-to type:
const int *p;
int const *p;
Both of the above declare p as a pointer to a const int object. You can write a new value to p setting it to point to a different object:
const int x = 1;
const int y = 2;
const int *p = &x;
p = &y;
but you cannot write to the pointed-to object:
*p = 3; // constraint violation, the pointed-to object is const
However,
int * const p;
declares p as a const pointer to a non-const int; you can write to the thing p points to
int x = 1;
int y = 2;
int * const p = &x;
*p = 3;
but you can't set p to point to a different object:
p = &y; // constraint violation, p is const
Which brings us to the third piece of the puzzle - why declarations are structured this way.
The intent is that the structure of a declaration should closely mirror the structure of an expression in the code ("declaration mimics use"). For example, let's suppose we have an array of pointers to int named ap, and we want to access the int value pointed to by the i'th element. We would access that value as follows:
printf( "%d", *ap[i] );
The expression *ap[i] has type int; thus, the declaration of ap is written as
int *ap[N]; // ap is an array of pointer to int, fully specified by the combination
// of the type specifier and declarator
The declarator *ap[N] has the same structure as the expression *ap[i]. The operators * and [] behave the same way in a declaration that they do in an expression - [] has higher precedence than unary *, so the operand of * is ap[N] (it's parsed as *(ap[N])).
As another example, suppose we have a pointer to an array of int named pa and we want to access the value of the i'th element. We'd write that as
printf( "%d", (*pa)[i] );
The type of the expression (*pa)[i] is int, so the declaration is written as
int (*pa)[N];
Again, the same rules of precedence and associativity apply. In this case, we don't want to dereference the i'th element of pa, we want to access the i'th element of what pa points to, so we have to explicitly group the * operator with pa.
The *, [] and () operators are all part of the expression in the code, so they are all part of the declarator in the declaration. The declarator tells you how to use the object in an expression. If you have a declaration like int *p;, that tells you that the expression *p in your code will yield an int value. By extension, it tells you that the expression p yields a value of type "pointer to int", or int *.
So, what about things like cast and sizeof expressions, where we use things like (int *) or sizeof (int [10]) or things like that? How do I read something like
void foo( int *, int (*)[10] );
There's no declarator, aren't the * and [] operators modifying the type directly?
Well, no - there is still a declarator, just with an empty identifier (known as an abstract declarator). If we represent an empty identifier with the symbol λ, then we can read those things as (int *λ), sizeof (int λ[10]), and
void foo( int *λ, int (*λ)[10] );
and they behave exactly like any other declaration. int *[10] represents an array of 10 pointers, while int (*)[10] represents a pointer to an array.
And now the opinionated portion of this answer. I am not fond of the C++ convention of declaring simple pointers as
T* p;
and consider it bad practice for the following reasons:
It's not consistent with the syntax;
It introduces confusion (as evidenced by this question, all the duplicates to this question, questions about the meaning of T* p, q;, all the duplicates to those questions, etc.);
It's not internally consistent - declaring an array of pointers as T* a[N] is asymmetrical with use (unless you're in the habit of writing * a[i]);
It cannot be applied to pointer-to-array or pointer-to-function types (unless you create a typedef just so you can apply the T* p convention cleanly, which...no);
The reason for doing so - "it emphasizes the pointer-ness of the object" - is spurious. It cannot be applied to array or function types, and I would think those qualities are just as important to emphasize.
In the end, it just indicates confused thinking about how the two languages' type systems work.
There are good reasons to declare items separately; working around a bad practice (T* p, q;) isn't one of them. If you write your declarators correctly (T *p, q;) you are less likely to cause confusion.
I consider it akin to deliberately writing all your simple for loops as
i = 0;
for( ; i < N; )
{
...
i++;
}
Syntactically valid, but confusing, and the intent is likely to be misinterpreted. However, the T* p; convention is entrenched in the C++ community, and I use it in my own C++ code because consistency across the code base is a good thing, but it makes me itch every time I do it.
I will be using C terminology - the C++ terminology is a little different, but the concepts are largely the same.
As others mentioned, 4, 5, and 6 are the same. Often, people use these examples to make the argument that the * belongs with the variable instead of the type. While it's an issue of style, there is some debate as to whether you should think of and write it this way:
int* x; // "x is a pointer to int"
or this way:
int *x; // "*x is an int"
FWIW I'm in the first camp, but the reason others make the argument for the second form is that it (mostly) solves this particular problem:
int* x,y; // "x is a pointer to int, y is an int"
which is potentially misleading; instead you would write either
int *x,y; // it's a little clearer what is going on here
or if you really want two pointers,
int *x, *y; // two pointers
Personally, I say keep it to one variable per line, then it doesn't matter which style you prefer.
#include <type_traits>
std::add_pointer<int>::type test, test2;
In 4, 5 and 6, test is always a pointer and test2 is not a pointer. White space is (almost) never significant in C++.
The rationale in C is that you declare the variables the way you use them. For example
char *a[100];
says that *a[42] will be a char. And a[42] a char pointer. And thus a is an array of char pointers.
This because the original compiler writers wanted to use the same parser for expressions and declarations. (Not a very sensible reason for a langage design choice)
I would say that the initial convention was to put the star on the pointer name side (right side of the declaration
in the c programming language by Dennis M. Ritchie the stars are on the right side of the declaration.
by looking at the linux source code at https://github.com/torvalds/linux/blob/master/init/main.c
we can see that the star is also on the right side.
You can follow the same rules, but it's not a big deal if you put stars on the type side.
Remember that consistency is important, so always but the star on the same side regardless of which side you have choose.
In my opinion, the answer is BOTH, depending on the situation.
Generally, IMO, it is better to put the asterisk next to the pointer name, rather than the type. Compare e.g.:
int *pointer1, *pointer2; // Fully consistent, two pointers
int* pointer1, pointer2; // Inconsistent -- because only the first one is a pointer, the second one is an int variable
// The second case is unexpected, and thus prone to errors
Why is the second case inconsistent? Because e.g. int x,y; declares two variables of the same type but the type is mentioned only once in the declaration. This creates a precedent and expected behavior. And int* pointer1, pointer2; is inconsistent with that because it declares pointer1 as a pointer, but pointer2 is an integer variable. Clearly prone to errors and, thus, should be avoided (by putting the asterisk next to the pointer name, rather than the type).
However, there are some exceptions where you might not be able to put the asterisk next to an object name (and where it matters where you put it) without getting undesired outcome — for example:
MyClass *volatile MyObjName
void test (const char *const p) // const value pointed to by a const pointer
Finally, in some cases, it might be arguably clearer to put the asterisk next to the type name, e.g.:
void* ClassName::getItemPtr () {return &item;} // Clear at first sight
The pointer is a modifier to the type. It's best to read them right to left in order to better understand how the asterisk modifies the type. 'int *' can be read as "pointer to int'. In multiple declarations you must specify that each variable is a pointer or it will be created as a standard variable.
1,2 and 3) Test is of type (int *). Whitespace doesn't matter.
4,5 and 6) Test is of type (int *). Test2 is of type int. Again whitespace is inconsequential.
I have always preferred to declare pointers like this:
int* i;
I read this to say "i is of type int-pointer". You can get away with this interpretation if you only declare one variable per declaration.
It is an uncomfortable truth, however, that this reading is wrong. The C Programming Language, 2nd Ed. (p. 94) explains the opposite paradigm, which is the one used in the C standards:
The declaration of the pointer ip,
int *ip;
is intended as a mnemonic; it says that the expression *ip is an
int. The syntax of the declaration for a variable mimics the syntax
of expressions in which the variable might appear. This reasoning
applies to function declarations as well. For example,
double *dp, atof(char *);
says that in an expression *dp and atof(s) have values of type
double, and that the argument of atof is a pointer to char.
So, by the reasoning of the C language, when you declare
int* test, test2;
you are not declaring two variables of type int*, you are introducing two expressions that evaluate to an int type, with no attachment to the allocation of an int in memory.
A compiler is perfectly happy to accept the following:
int *ip, i;
i = *ip;
because in the C paradigm, the compiler is only expected to keep track of the type of *ip and i. The programmer is expected to keep track of the meaning of *ip and i. In this case, ip is uninitialized, so it is the programmer's responsibility to point it at something meaningful before dereferencing it.
A good rule of thumb, a lot of people seem to grasp these concepts by: In C++ a lot of semantic meaning is derived by the left-binding of keywords or identifiers.
Take for example:
int const bla;
The const applies to the "int" word. The same is with pointers' asterisks, they apply to the keyword left of them. And the actual variable name? Yup, that's declared by what's left of it.

Declaration of a function pointer's typedef in C++

I understand that similar questions with answers have been asked before. I already understand the concept of a function pointer and the meaning of its declaration. Following is my sample code of a function's pointer, where I assign the function pointer fp_GetBiggerElement to point to the function GetBiggerElement
#include <iostream>
typedef int (*fp_GetBiggerElement) (int, int);
// ^ ^ ^
// return type type name arguments
using namespace std;
int GetBiggerElement(int arg1, int arg2)
{
int bigger = arg1 > arg2 ? arg1 : arg2;
return bigger;
}
int main()
{
fp_GetBiggerElement funcPtr = GetBiggerElement;
int valueReturned = funcPtr(10, 20);
cout << valueReturned << endl;
return 0;
}
What I understand is, typedef means to assing a new definition for a type. Usually, the typedef statement needs two-parts(or say two-arguments)
first part is the type which needs a new alias
second part is a new alias name
typedef unsigned int UnsignedInt;
// ^ ^
// (original type) (Alias)
for example, in the code above, the first part is unsigned int and the second part is UnsignedInt
typedef char * CharPtr;
// ^ ^
// (original type) (Alias)
similarly, in the second example above, the first part is char* and the second part is CharPtr
QUESTION: I am confused with the FORMAT of the typedef statement for a function pointer. In the statement typedef int(*fp_GetBiggerElement)(int, int);, the typical two-arguments format for typedef is not followed then, how is it working?
UPDATE: I am aware that C++11 offers another way of declaring function pointer i.e. (by using statment). In this question, I am only interested to understand the syntax of typedef statement for a fucntion pointer.
I think the best idea to think about typedef syntax is like declaring variable of type you want to typedef. For example:
char *CharPtr;// declare CharPtr to be variable of type char*
typedef char *CharPtr_t;// declare CharPtr_t to be alias of type char*
Similarly with function pointers:
int (*fp) (int, int);// declare fp as pointer to int(int, int)
typedef int (*fp_t)(int, int);// declare fp_t to be alias of pointer to int(int, int)
Btw, in C++11 and further you get not-so-confusing (and more powerful) alternative to typedef - using. You should be using (pun intended) it instead. Just look:
using fp = int (*)(int, int);// declare fp_t to be alias of pointer to int(int, int)
typedef uses the same syntax as a variable declaration, but declares a type name rather than a variable name.
The parts are "intermingled" in a somewhat peculiar (some would call it "wtf?") way - a variable declaration has the same form as its use, which simplifies the parser and enables reusing code in the compiler.
It makes more sense if you read in a more "old-school" way:
int *p;
"*p is an int"
(Equivalent translation: "p is a pointer to int")
int *p, x;
"*p and x are both ints"
("p is a pointer to int, and x is an int")
int (*q)[3];
"*q is an array of three ints", or "(*q)[x] is an int"
("q is a pointer to an array of three ints")
int (*fp)(int,int);
"*fp is a function that takes two ints and returns an int"
("fp is a pointer to a function that takes two ints and returns an int")
int (*(*foo)())[3];
"*(*foo)() is an array of three ints" (alternatively, "(*(*foo)())[x] is an int) - or, in other words,
"(*foo)() is a pointer to an array of three ints" - or, in other words,
"foo is a pointer to a function that takes no arguments and returns a pointer to an array of three ints"
A slightly unreadable effect of this is that
int *p, x, (*q)[3], (*fp)(int,int), (*(*foo)())[3];
declares all of the above at once.
That's just the syntax for function pointers.
You would see the same thing if you just declare a variable.
int foo; // Normal
int (*bar)(int, int); // bar is of type int(*)(int,int)
Personally i prefer to use using = ... which in my opinion is more clear.
using fp_GetBiggerElement = int (*)(int,int);
This syntax comes from the C-way of reading variables.
Ever wondered why we need an asterisk, for every pointer we want to declare in a single expression?
int *p1, *p2, p3; // p3 is not a pointer
C++ people generally tend to see a variable having a specific type, which can be a pointer (in other words, they see the pointer characteristics as property of the type). That's why they usually prefer writing
int* p1; // notice asterisk grouped with type
C people rather read as: I have a variable p1, and if I dereference it, I get type int (so p1 being a pointer is deduced information, i. e. they see the pointer characteristics rather as property of the variable; and that's why they rather group the asterisk to the name: int *p1;).
Pretty similar for function pointers:
int (*fp) (int, int);
I have a variable fp, and if I dereference it, I get int (int, int). Same pattern then for the typedef. On the other hand, the (new) C++ way for defining an alias reflects much better the C++ way of thinking:
using fp = int (*)(int, int);
I have a variable, and it's type is a pointer (to whatever) right from the start – well, not fully consistently, though: With C++ way of thinking, function pointers might rather look like int(int, int)* or maybe requiring parentheses (int(int, int))*, but OK, that's not the way it is (wanting to stay compatible with C being reason for).
typedef declarations are similar to simple declarations but instead of declaring an identifier of a derclarator as an identifier of an object or a function they declare an identifier of a declarator as an alias for the specified type.
Consider the following examples of simple declarations
int x;
unsigned int a[10][20];
int unsigned ( *p )[10][20];
void ( *f )( int, int );
double h( double );
They declare several objects and the function h.
Now place in these declarations decl-specifier typedef (in any order relative to other decl-specifiers) and you will get that the declared identifiers become aliases of types.
typedef int x;
unsigned typedef int a[10][20];
int unsigned typedef ( *p )[10][20];
void typedef ( *f )( int, int );
typedef double h( double );
That is x is an alias of the type int. a is an alias for the type unsigned int [10][20]. p is an alias for the pointer type unsigned int ( * )[10][20]. f is an alias for the function pointer void ( * )( int, int ). And h in an alias for the function type double( double ).

Semantic difference between different pointer syntax in c++?

In C++, is this form int *p semantically different than this one int* p? Or is this clearly a matter of style?
Now this question may be dumb, but I remember that I had seen somewhere both styles being used at the same time, something that led to me to believe that there may be different semantics between those forms.
They're the same.
That's tricky sometimes, since
int* a, b;
defines one pointer and one int. This style makes it more clear:
int *a, b;
It has the same semantic meaning.
If you are using const keyword be aware of the caveats:
int * conts p; - const pointer to int versus
int const * p; - non const pointer to const int.
As others have said, they're the same.
The fact that int* a, b; declares one pointer and one integer is one aspect of a wart that manifests in other ways too. E.g.:
int* a, f(double), c[42];
declares a pointer to int called a, a function that takes a double and returns an int called f, and an array of 42 ints called c. That's because all of these "decorations" (*, (), []) form part of the C++ grammar called the declarator, which is associated with an individual name, rather than with the statement as a whole (which is called a declaration in the grammar).

What are the distinctions between the various symbols (*,&, etc) combined with parameters? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
c++ * vs & in function declaration
I know that this probably seems like an incredibly elementary question to many of you, but I have genuinely had an impossible time finding a good, thorough explanation, despite all my best Googling. I'm certain that the answer is out there, and so my search terms must be terrible.
In C++, a variety of symbols and combinations thereof are used to mark parameters (as well as arguments to those parameters). What, exactly, are their meanings?
Ex: What is the difference between void func(int *var) and void func(int **var)? What about int &var?
The same question stands for return types, as well as arguments. What does int& func(int var) mean, as compared to int* func(int var)? And in arguments, how does y = func(*x) differ from y = func(&x)?
I am more than happy to read enormous volumes on the subject if only you could point me in the right direction. Also, I'm extremely familiar with general programming concepts: OO, generics/templates, etc., just not the notation used in C/C++.
EDIT: It seems I may have given the impression that I do not know what pointers are. I wonder how that could be :)
So for clarification: I understand perfectly how pointers work. What I am not grasping, and am weirdly unable to find answers to, is the meaning of, for example 'void func(int &var)'. In the case of an assignment statement, the '&' operator would be on the right hand side, as in 'int* x = &y;', but in the above, the '&' operator is effectively on the left hand side. In other words, it is operating on the l-value, rather than the r-value. This clearly cannot have the same meaning.
I hope that I'm making more sense now?
To understand this you'll first need to understand pointers and references. I'll simply explain the type declaration syntax you're asking about assuming you already know what pointers and references are.
In C, it is said that 'declaration follows use.' That means the syntax for declaring a variable mimics using the variable: generally in a declaration you'll have a base type like int or float followed something that looks like an expression. For example in int *y the base type is int and the expression look-alike is *y. Thereafter that expression evaluates to a value with the given base type.
So int *y means that later an expression *y is an int. That implies that y must be a pointer to an int. The same holds true for function parameters, and in fact for whole function declarations:
int *foo(int **bar);
In the above int **bar says **bar is an int, implying *bar is a pointer to an int, and bar is a pointer to a pointer to an int. It also declares that *foo(arg) will be an int (given arg of the appropriate type), implying that foo(arg) results in a pointer to an int.¹ So the whole function declaration reads "foo is a function taking a pointer to a pointer to an int, and returning a pointer to an int."
C++ adds the concept of references, and messes C style declarations up a little bit in the process. Because taking the address of a variable using the address-of operator & must result in a pointer, C doesn't have any use for & in declarations; int &x would mean &x is an int, implying that x is some type where taking the address of that type results in an int.² So because this syntax is unused, C++ appropriates it for a completely different purpose.
In C++ int &x means that x is a reference to an int. Using the variable does not involve any operator to 'dereference' the reference, so it doesn't matter that the reference declarator symbol clashes with the address-of operator. The same symbol means completely different things in the two contexts, and there is never a need to use one meaning in the context where the other is allowed.
So char &foo(int &a) declares a function taking a reference to an int and returning a reference to a char. func(&x) is an expression taking the address of x and passing it to func.
1. In fact in the original C syntax for declaring functions 'declarations follow use' was even more strictly followed. For example you'd declare a function as int foo(a,b) and the types of parameters were declared elsewhere, so that the declaration would look exactly like a use, without the extra typenames.
2. Of course int *&x; could make sense in that *&x could be an int, but C doesn't actually do that.
What you're asking about are called pointers (*), and reference to (&), which I think is best explained here.
The symbols & and * are used to denote a reference and pointer type, respectively.
int means simply the type 'int',
int* means 'pointer to int',
int& means 'reference to int',
A pointer is a variable which is used to store the address of a variable.
A reference has the syntax of its base type, but the semantics of a pointer to that type. This means you don't need to dereference it in order to change the value.
To take an example, the following code blocks two are semantically equivalent:
int* a = &value;
*a = 0;
And:
int& a = value;
a = 0;
The main reasons to use pointers or references as an argument type is to avoid copying of objects and to be able to change the value of a passed argument. Both of these work because, when you pass by reference, only the address is copied, giving you access to the same memory location as was "passed" to the function.
In contrast, if a reference or pointer type is not used, a full copy of the argument will be made, and it is this copy which is available inside the function.
The symbols * and & have three meanings each in C++:
When applied to an expression, they mean "dereference" and "address-of" respectively, as you know.
When part of a type, they mean "pointer" and "reference", respectively.
Since C++ doesn't care about arbitrary spacing, the declaration int *ptr is exactly the same as the declaration int* ptr, in which you can now more clearly see that this is an object called ptr of type int*.1
When used between two expressions, they mean "multiply" and "bitwise AND", respectively.
1 - though, frustratingly, this isn't actually how the internal grammar reads it, thanks to the nasty legacy of C's type system. So avoid single-line multi-declarations involving pointers unless you want a surprise.
Ex: What is the difference between 'void func(int *var)' and 'void
func(int **var)'? What about 'int &var'?
The same question stands for return types, as well as arguments. What
does 'int& func(int var)' mean, as compared to 'int* func(int var)'?
And in arguments, how does 'y = func(*x)' differ from 'y = func(&x)'?
(1)
<return type> <function name> <parameters>
void func (int *var)
<parameter> here int *var is a pointer to integer, ie it can point to
an array or any buffer that should be handled with integer pointer
arithmetic. In simple terms , var holds the address of the respective
**actual parameter.**
eg: int arr[10];
func(arr);
int a = 33;
func(&a);
Here, &a means we are explicitly passing address of the the variable 'a'.
(2)
int m = 0;
int &var = m;
Here var means reference, ie it another alias name for variable 'm' ,
so any change 'var' makes will change the contents of variable 'm'.
var = 2; /* will change the actual contents of 'm' */
This simple example will not make sense , unless you understand the context.
Reference are usually use to pass parameter to function, so that changes made by
the function to the passed variable is visible at the caller.
int swap(int &m, int &n) {
tmp = m;
m = n;
n = tmp;
}
void main( void ) {
int x = 1, y = 2;
swap(x, y);
/* x = 2, y =1 */
}
(3)
'int& func(int var)' mean, as compared to 'int* func(int var)'?
int& func(int var) means the function returns a reference;
int* func(int var) means the function returns a pointer / address;
Both of the them has its context;
int& setNext() {
return next;
}
setNext() = previous;
where as
int* setNext() {
return &next;
}
int *inptr;
inptr = setNext();
*inptr = previous;
In the previous two lines,
int *inptr <- integer pointer declaration;
*inptr <- means we are accessing contents of the address pointed by inptr;
ie we are actually referring to 'next' variable.
The actual use is context specific. It can't be generalized.
(4)
how does 'y = func(*x)' differ from 'y = func(&x)'?
y = func(&x) is already explained.
y = func(*x) , well i'm not sure if you actually meant *x.
int swap(int *m, int *n) {
tmp = *m;
*m = *n;
*n = tmp;
}