int (*ptr)(char (*ch)[]);
What does the above declaration means? Does it mean
ptr is pointer to a function that accepts an argument which is array of pointers to characters returning integer?
How to evaluate?
ptr is pointer to a function that accepts an argument which is a pointer to an array of characters, returning integer.
There's rule: http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html
Briefly, you should start from identifier, then parse everything from identifier to the right (it can be () - function or [] array), then parse everything from identifier to the left. Parentheses changes this order - you should parse everything in the most inner parentheses first and so on, it works like with arithmetic calculations.
In other words, there is an order of precedence (which can be changed by parentheses), from higher to lower:
1) () - function and [] - array, from left to right;
2) * - pointer, type, type modifier, from right to left.
Your example
int (*ptr)(char (*ch)[])
We start from identifier
int (*ptr)(char (*ch)[]); // (1)ptr
|_|
1
Identifier ptr is in parentheses, so we parse everything in parenteses first
(*ptr) // (1)ptr
|_|
1
There's nothing to the right, so we parse to the left
(*ptr) // (1)ptr is (2)a pointer
||_|
2 1
We finished in parentheses, now we parse to the right of parentheses
int (*ptr)(char (*ch)[]); // (1)ptr is (2)a pointer to (3)function
||_| |____________|
2 1 3
So far we ignore function arguments and parse to the left of parentheses
int (*ptr)(char (*ch)[]); // (1)ptr is (2)a pointer to (3)function which returns (4)int
|_| ||_| |____________|
4 2 1 3
In the same way we parse argument of function (I've inserted some spaces for better alignment)
char (* ch )[ ] // (1)ch is (2)a pointer to (3)array of (4)chars
|___| | |_| |_|
4 2 1 3
Finally, we have:
ptr is a pointer to function which returns int and accepts a pointer to array of chars as argument
As you have written, ptr is a pointer to a function that returns int, and takes as an argument a pointer to an array of char.
However, you are not allowed to have a pointer to an array without a bound on the array. So, your variable is incorrectly specified, and will not compile. It seems you want ptr to have a type that can accept a pointer to a function that can take any size array. This requires a template construction. For a function argument, it would have the form:
template <unsigned N>
int foo (int (*ptr)(char (*)[N])) {
//...
}
Normally, the way to simplify such types is to use typedef to represent the complicated parts, so that the variable itself becomes a simple pointer to some type. This is particularly useful when trying to write a function that returns a function pointer.
void x (char *s) {}
typedef void xtype (char *);
void (* y_hard ())(char *) { return x; }
xtype * y_easy () { return x; }
However, the parameterized nature of the function argument makes that harder to achieve. Assuming C++ 11, you can use the following construct (thanks to this answer):
template <unsigned N>
using ArrayArg = const char [N];
template <unsigned N>
using Function = int (ArrayArg<N> *);
template <unsigned N>
int foo (Function<N> *ptr) {
//...
}
It works fine in GCC.
Yes ptr is a function pointer. It is a pointer to a function returning an integer and accepting a pointer to a character array as argument.
Consider the function fun with the following prototype,
int fun(char (*ptr)[]);
fun() is a function accepting a pointer to a character array as argument.
and the following piece of code compile without any error or warning,
int (*ptr)(char (*ch)[]);
ptr=fun;
Related
At xdn-project/digitalnote ./src/crypto/crypto.cpp file there is an error at line 338 when compiling (using cmake):
return sizeof(rs_comm) + pubs_count * sizeof(rs_comm().ab[0]);
^
error: value-initialization of incomplete type
‘Crypto::rs_comm:: []’
I found the solution on cryptonotefoundation/cryptonote:
return sizeof(rs_comm) + pubs_count * sizeof(((rs_comm*)0)->ab[0]);
I can play with Java JDK quite well, but currently at C++ need help :) It would be nice to see detail explanation of this code part:
sizeof(((rs_comm*)0)->ab[0]);
My questions are:
Asterisk after rs_comm - what its for?
0) - what is the purpose of 0 here?
The fragment of code:
struct rs_comm {
Hash h;
struct {
EllipticCurvePoint a, b;
} ab[];
};
static inline size_t rs_comm_size(size_t pubs_count) {
return sizeof(rs_comm) + pubs_count * sizeof(rs_comm().ab[0]);
}
sizeof is an operator that return the size of a specific type. It can work directly with a type or with an expression.
This part (rs_comm*)0 is taking 0 (0 is a valid null pointer constant) and casting it to a pointer of the struct rs_comm (or the class, I don't know the definition of rs_comm, but I am guessing).
Now, it is accessing using the -> operator to the data-member ab. ab has to be define as array, so it can get the first item in the array.
Because, sizeof doesn't really evaluate the expression but just figuring out the type and get the size of it.
So, the final result is the size of the first element in the array ab for the class/struct rs_comm.
So ab is an member of struct rs_comm, and is an array.
If you have a rs_comm object, i.e. rs_comm rs;, but you don't know the type of ab, you want to know its size, sizeof(rs.ab[0]) will do.
If you have a pointer to rs_comm, i.e. rs_comm *p_rs;, then sizeof(p_rs->ab[0]) will do the same thing.
If you don't have a rs_comm object nor a pointer to rs_comm, you can change a NULL pointer to a pointer to rs_comm, this is what ((rs_comm *)0) do.
Replace the p_rs in sizeof(p_rs->ab[0]) with ((rs_comm *)0), you get sizeof(((rs_comm *)0)->ab[0]).
sizeof(variable) .
return the size variable data type .
like
char x ;
cout << sizeof(x) ;
the result would be
#include <iostream>
using namespace std;
int func(int arg0, int *arg1, int *arg2);
int main() {
int *b;
int z;
int a[10];
z = func(*a[0], &a[z], b+a[4]);
}
The following code above gives me an error "invalid type argument of unary '*' (have 'int')". I know that * when used in a declaration creates a pointer and when used with a variable name it gets the value stored at that pointer. In the function func(), it takes 3 parameters, 1 int and 2 int pointers. I think that the first argument passed into the function is giving me an error but I am not understanding why. Shouldn't *a[0] get the value of the first element in the a array which was declared as an int?
No, the * when used on a pointer dereferences the pointer. But a[0] is already equivalent to:
*(a + 0) // And since the offset is 0, this is equivalent to *a.
In other words, dereferencing a pointer to the beginning of the array that has been offset to give you the value of the item at a given 'index'. What YOU wrote is equivalent to:
**(a + 0) // And since the offset is 0, this is equivalent to **a.
Therefore, you are trying to 'dereference' an int, which won't work. Since * is not a valid unary operator for an int, that fails and causes the error you've seen to appear.
*a[0] is the same as **a.
Given the declaration int a[10];, it should be fairly clear that you are not able to dereference a twice.
If you want the first element of the array a, then that is simply a[0].
You could also simplify your example to this, and still get the same error:
int main() {
int a[10];
int b = *a[0];
}
What is the difference between the following declarations:
int* arr1[8];
int (*arr2)[8];
int *(arr3[8]);
What is the general rule for understanding more complex declarations?
int* arr[8]; // An array of int pointers.
int (*arr)[8]; // A pointer to an array of integers
The third one is same as the first.
The general rule is operator precedence. It can get even much more complex as function pointers come into the picture.
Use the cdecl program, as suggested by K&R.
$ cdecl
Type `help' or `?' for help
cdecl> explain int* arr1[8];
declare arr1 as array 8 of pointer to int
cdecl> explain int (*arr2)[8]
declare arr2 as pointer to array 8 of int
cdecl> explain int *(arr3[8])
declare arr3 as array 8 of pointer to int
cdecl>
It works the other way too.
cdecl> declare x as pointer to function(void) returning pointer to float
float *(*x)(void )
I don't know if it has an official name, but I call it the Right-Left Thingy(TM).
Start at the variable, then go right, and left, and right...and so on.
int* arr1[8];
arr1 is an array of 8 pointers to integers.
int (*arr2)[8];
arr2 is a pointer (the parenthesis block the right-left) to an array of 8 integers.
int *(arr3[8]);
arr3 is an array of 8 pointers to integers.
This should help you out with complex declarations.
int *a[4]; // Array of 4 pointers to int
int (*a)[4]; //a is a pointer to an integer array of size 4
int (*a[8])[5]; //a is an array of pointers to integer array of size 5
The answer for the last two can also be deducted from the golden rule in C:
Declaration follows use.
int (*arr2)[8];
What happens if you dereference arr2? You get an array of 8 integers.
int *(arr3[8]);
What happens if you take an element from arr3? You get a pointer to an integer.
This also helps when dealing with pointers to functions. To take sigjuice's example:
float *(*x)(void )
What happens when you dereference x? You get a function that you can call with no arguments. What happens when you call it? It will return a pointer to a float.
Operator precedence is always tricky, though. However, using parentheses can actually also be confusing because declaration follows use. At least, to me, intuitively arr2 looks like an array of 8 pointers to ints, but it is actually the other way around. Just takes some getting used to. Reason enough to always add a comment to these declarations, if you ask me :)
edit: example
By the way, I just stumbled across the following situation: a function that has a static matrix and that uses pointer arithmetic to see if the row pointer is out of bounds. Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_ELEM(ar) (sizeof(ar) / sizeof((ar)[0]))
int *
put_off(const int newrow[2])
{
static int mymatrix[3][2];
static int (*rowp)[2] = mymatrix;
int (* const border)[] = mymatrix + NUM_ELEM(mymatrix);
memcpy(rowp, newrow, sizeof(*rowp));
rowp += 1;
if (rowp == border) {
rowp = mymatrix;
}
return *rowp;
}
int
main(int argc, char *argv[])
{
int i = 0;
int row[2] = {0, 1};
int *rout;
for (i = 0; i < 6; i++) {
row[0] = i;
row[1] += i;
rout = put_off(row);
printf("%d (%p): [%d, %d]\n", i, (void *) rout, rout[0], rout[1]);
}
return 0;
}
Output:
0 (0x804a02c): [0, 0]
1 (0x804a034): [0, 0]
2 (0x804a024): [0, 1]
3 (0x804a02c): [1, 2]
4 (0x804a034): [2, 4]
5 (0x804a024): [3, 7]
Note that the value of border never changes, so the compiler can optimize that away. This is different from what you might initially want to use: const int (*border)[3]: that declares border as a pointer to an array of 3 integers that will not change value as long as the variable exists. However, that pointer may be pointed to any other such array at any time. We want that kind of behaviour for the argument, instead (because this function does not change any of those integers). Declaration follows use.
(p.s.: feel free to improve this sample!)
typedef int (*PointerToIntArray)[];
typedef int *ArrayOfIntPointers[];
As a rule of thumb, right unary operators (like [], (), etc) take preference over left ones. So, int *(*ptr)()[]; would be a pointer that points to a function that returns an array of pointers to int (get the right operators as soon as you can as you get out of the parenthesis)
I think we can use the simple rule ..
example int * (*ptr)()[];
start from ptr
" ptr is a pointer to "
go towards right ..its ")" now go left its a "("
come out go right "()" so
" to a function which takes no arguments " go left "and returns a pointer " go right "to
an array" go left " of integers "
Here's an interesting website that explains how to read complex types in C:
http://www.unixwiz.net/techtips/reading-cdecl.html
Here's how I interpret it:
int *something[n];
Note on precedence: array subscript operator ([]) has higher priority than
dereference operator (*).
So, here we will apply the [] before *, making the statement equivalent to:
int *(something[i]);
Note on how a declaration makes sense: int num means num is an int, int *ptr or int (*ptr) means, (value at ptr) is
an int, which makes ptr a pointer to int.
This can be read as, (value of the (value at ith index of the something)) is an integer. So, (value at the ith index of something) is an (integer pointer), which makes the something an array of integer pointers.
In the second one,
int (*something)[n];
To make sense out of this statement, you must be familiar with this fact:
Note on pointer representation of array: somethingElse[i] is equivalent to *(somethingElse + i)
So, replacing somethingElse with (*something), we get *(*something + i), which is an integer as per declaration. So, (*something) given us an array, which makes something equivalent to (pointer to an array).
I guess the second declaration is confusing to many. Here's an easy way to understand it.
Lets have an array of integers, i.e. int B[8].
Let's also have a variable A which points to B. Now, value at A is B, i.e. (*A) == B. Hence A points to an array of integers. In your question, arr is similar to A.
Similarly, in int* (*C) [8], C is a pointer to an array of pointers to integer.
int *arr1[5]
In this declaration, arr1 is an array of 5 pointers to integers.
Reason: Square brackets have higher precedence over * (dereferncing operator).
And in this type, number of rows are fixed (5 here), but number of columns is variable.
int (*arr2)[5]
In this declaration, arr2 is a pointer to an integer array of 5 elements.
Reason: Here, () brackets have higher precedence than [].
And in this type, number of rows is variable, but the number of columns is fixed (5 here).
In pointer to an integer if pointer is incremented then it goes next integer.
in array of pointer if pointer is incremented it jumps to next array
I was just going through some code on the Internet and found this:
float * (*(*foo())[SIZE][SIZE])()
How do I read this declaration? Is there a specific set of rules for reading such complex declarations?
I haven't done this in a while!
Start with foo and go right.
float * (*(*foo())[SIZE][SIZE])()
foo is a function with no arguments...
Can't go right since there's a closing parenthesis. Go left:
float * (*(* foo())[SIZE][SIZE])()
foo is a function with no arguments returning a pointer
Can't go left further, so let's cross the parentheses and go right again
float * (*(* foo())[SIZE][SIZE])()
float * (*(* foo())[SIZE][SIZE])()
float * (*(* foo())[SIZE][SIZE])()
foo is a function with no arguments returning a pointer to an array of SIZE arrays of SIZE ...
Closing parenthesis reached, left again to reach a pointer symbol:
float * (*(* foo())[SIZE][SIZE])()
foo is a function with no arguments returning a pointer to an array of SIZE arrays of SIZE pointers to ...
Left parenthesis again, so we cross it and go right again:
float *( *(* foo())[SIZE][SIZE])()
float *( *(* foo())[SIZE][SIZE])()
foo is a function with no arguments returning a pointer to an array of SIZE arrays of SIZE pointers to a function with no arguments...
And left to the end
float * ( *(* foo())[SIZE][SIZE])()
foo is a function with no arguments returning a pointer to an array of SIZE arrays of SIZE pointers to a function with no arguments returning a pointer to float
And whoever wrote that, please teach him to use typedef:
// Function that returns a pointer to float
typedef float* PFloatFunc ();
// Array of pointers to PFloatFunc functions
typedef PFloatFunc* PFloatFuncArray2D[SIZE][SIZE];
// Function that returns a pointer to a PFloatFuncArray2D
PFloatFuncArray2D* foo();
Standard rule: find the leftmost identifier and work your way out, remembering that [] and () bind before *:
foo -- foo
foo() -- is a function
*foo() -- returning a pointer
(*foo())[SIZE] -- to a SIZE-element array
(*foo())[SIZE][SIZE] -- of SIZE-element arrays
*(*foo())[SIZE][SIZE] -- of pointers
(*(*foo())[SIZE][SIZE])() -- to functions
* (*(*foo())[SIZE][SIZE])() -- returning pointers
float * (*(*foo())[SIZE][SIZE])(); -- to float
So imagine you have a bunch of functions returning pointers to float:
float *quux();
float *bar();
float *bletch();
float *blurga();
Let's say you want to store them in a 2x2 table:
float *(*tab[SIZE][SIZE])() = {quux, bar, bletch, blurga};
tab is a SIZE x SIZE array of pointers to functions returning pointers to float.
Now let's decide we want a function to return a pointer to that table:
float *(*(*foo())[SIZE][SIZE])()
{
static float *(*tab[SIZE][SIZE])() = {quux, bar, bletch, blurga};
return &tab;
}
Note that you could have several functions that build tables of different functions, or organize the same functions differently:
float *(*(*qwerbl())[SIZE][SIZE])()
{
static float *(*tab[SIZE][SIZE])() = {blurga, bletch, bar, quux};
return tab;
}
which is the only reason I can think of to do something like this. You shouldn't see types like this in the wild very often (although they do crop up occasionally, and I've been guilty of writing something similarly heinous).
According to cdecl.org
declare foo as function returning pointer to array SIZE of array SIZE
of pointer to function returning pointer to float
Use the spiral rule given by Luchian Grigore if you want to decode it by hand.
The best thing to do here is convert to a series of typedefs.
typedef float * fnReturningPointerToFloat();
typedef fnReturningPointerToFloat* fnArray[SIZE][SIZE];
fnArray* foo();
Generally, you could try cdecl.org but you'd need to substitute for SIZE
Say you swap SIZE for 12, you'd get:
declare foo as function returning pointer to array 12 of array 12 of
pointer to function returning pointer to float
I'm not sure that really helps you!
Two observations here:
I'm guessing that this code didn't have a comment beside it explaining what the purpose of it was (i.e. not the technical explanation of what it is but what it is achieving from a functional / business perspective) If a programmer needs to use something as complex as this, they should be good enough to explain to future maintainers what purpose it serves.
Certainly in C++ there are more obvious and probably safer ways of achieving the same thing.
This document gaves me the best clue about how to easily ready any C declaration :
http://c-faq.com/decl/spiral.anderson.html
There are three simple steps to follow:
Starting with the unknown element, move in a spiral/clockwise direction; when ecountering 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!
Example :
+-------+
| +-+ |
| ^ | |
char *str[10];
^ ^ | |
| +---+ |
+-----------+
Question we ask ourselves: What is str?
``str is an...
- We move in a spiral clockwise direction starting with `str' and the first character we see is a `[' so, that means we have an array, so...
``str is an array 10 of...
- Continue in a spiral clockwise direction, and the next thing we encounter is the `*' so, that means we have pointers, so...
``str is an array 10 of pointers to...
- Continue in a spiral direction and we see the end of the line (the `;'), so keep going and we get to the type `char', so...
``str is an array 10 of pointers to char''
We have now ``visited'' every token; therefore we are done!
Although most of the answers above are good enough, there is a lack of complete set of rules for decoding complex C declarations. I have provided a complete set below to decode any complex C declaration. This set of rules is actually based on the precedence of operators. Rules such as right hand spiral rules can be thought of as a shortcut for these set of rules.
Before anything else we need to know a few things to decode the declaration.
'Basic Type' of a declaration
A C declaration always has only one basic declaration type. This is at the left most position of a declaration.
For example -
int a - basic type is 'int'
float *p - basic type is 'float'
char (*p)[3] - basic type is 'char'
Precedence and associativity
Next we need to know the precedence order of (), [], and * - dereference operator
(), [] - Associativity is left to right
* - Associativity is right to left
Phrase corresponding to each of the operator above
Next we need to know the decoded phrase corresponding to each operator. Examples ahead will make this point clear.
() - function returning
[SIZE] - array of SIZE
* - pointer to
Now follow the rules below to decode the declaration
Always write the variable name first followed by an 'is'.
For example -
int a - a is ...
float *p - p is ...
char (*p)[3] - p is ...
Always end with basic type
For example -
int a - a is ... int
float *p - p is ... float
char (*p)[3] - p is ... char
Now fill the part in between using the following sub-steps
Starting from the name, follow the operator precedence and associativity to choose next highest priority operator and append the phrase corresponding to it to the middle part of the decoded string.
Repeat the sub step above for the remaining declaration until the decoding process is complete
NOTE 1: For simplicity, I have ignored the arguments of the function however it can be included just after the phrase corresponding to ().
NOTE 2: Parenthesis(()) change the priority order of operators, just like in any arithmetic expression.
NOTE 3: You can use parenthesis in the decoded declaration to increase readability( I have done it in some examples below). Think of each set of () as a single unit.
NOTE 4: A n dimensional array is actually an array of array of ... (n-1 times) array. For ex - int A[2][3] - A is array of 2 (array of 3 int) i.e A is an array of 2 elements in which each element is an array containing 3 integers
Examples
int a - a is int
float *p - p is pointer to float
char (*p)[3] - p is pointer to array of 3 char
Some complex declaration examples
int **p[10] - p is array of 10 pointer to pointer to int
int (*p)[10] - p is pointer to array of 10 int
int *p(char *a) - p is function returning pointer to int
int (*p(char*a))[10] - p is function returning (pointer to (array of 10 int))
int *(*p)() - p is pointer to (function returning (pointer to int))
int (*p()[20])[10] - p is function returning (array of 20 (pointer to (array of 10 int)))
This set of rules can be used with const as well - const qualifier modifies the term to the left of it (if present) otherwise it modifies the term to the right of it.
const int *p[10] - p is array of 10 pointer to int const
int const *p[10] - p is array of 10 pointer to const int (this is same as 7th example)
int *const p[10] - p is array of 10 const pointer to int
Now a really complex example which will not find its use anywhere in practice but nevertheless can be used to demonstrate the decoding process
char *(*(**foo[][8])())[] - foo is array of (array of 8 (pointer to (pointer to (function returning (pointer to (array of (pointer to char)))))))
Now at last decoding for the declaration given in the question
float * (*(*foo())[SIZE][SIZE])() - foo is function returning (pointer to (array of SIZE (array of SIZE (pointer to (function returning pointer to float)))))
The following is the link for the article from which I read this decoding process
Example 10 has been taken from this article
http://www.unixwiz.net/techtips/reading-cdecl.html
from http://cdecl.org/
declare foo as function returning pointer to array SIZE of array SIZE of pointer to function returning pointer to float
From here: https://stackoverflow.com/a/3473454/499125
int ( &fillarr( int (&arr)[5] ) )[5] { // no decay; argument must be size 5
return arr;
}
The definition above can force the compiler to become size-aware of its parameters. This statement seems complex to me. Can someone give an anatomy of this statement or explain how does the statement achieves the size-awareness?
Can this be extended to handle multiple parameters?
It all boils down to being able to read the declaration. A simpler way of writing exactly the same would be:
typedef int int5[5]; // create a typedef
int5& fillarr( int5& ) {
}
As of the exact way of reading the original declaration, just break it into pieces:
int (&fillarr( int (&arr)[5] ))[ 5 ];
^^^^^^^^^^^^^ // A: reference to array of 5 int
^^^^^^ ^^^^^^ // B: reference to array of 5 int
^^^^^^^^ ^ // C: function taking A and returning B
You can split understanding this in two parts, 1) the return value and 2) the parameter type:
int ( &fillarr() )[5] {
static int arr[5];
return arr;
}
We can have a look at the type: int (&fillarr())[5]. To understand this, unfortunately the old C rule: "Declaration is like usage in expressions" doesn't work with references, so let's have a look at a similar declaration instead:
int (*fillarr())[5];
This is a function that returns a pointer instead of a reference to an array of size 5. How do I figure? Well, assume we do have a function f that returns a pointer to an array of ints, how would we access the fifth element? Let's see, we first have to call the function: f(). Then we have to dereference the result *f() and then access the fifth element (which doesn't exist, but ignore that) (*f())[5] which is an int. This is exactly the declaration syntax:
int x;
int (*f())[5];
x = (*f())[5];
// ^^^-------- call f -> yields pointer to array of 5 ints
// ^----------- dereferene the result of f -> yields array of 5 ints
// ^^^---- access the fifth element
Now you only substitute the * for an & because you're returning a reference in your example.
The parameter syntax works analogously.