Easy rule to read complicated const declarations?
The const
modifier is trivial: it modifies what precedes it, unless
nothing precedes it. So:
char const* buffer; // const modifies char
char* const buffer; // const modifies *
, etc. Generally, It's best to avoid the forms where nothing precedes
the const
, but in practice, you're going to see them, so you have to
remember that when no type precedes the const
, you have to logically
move it behind the first type. So:
const char** buffer;
is in fact:
char const** buffer;
, i.e. pointer to pointer to const char.
Finally, in a function declaration, a []
after reads as a *
before.
(Again, it's probably better to avoid this misleading notation, but
you're going to see it, so you have to deal with it.) So:
char * const argv[], // As function argument
is:
char *const * argv,
a pointer to a const pointer to a char.
Spiral rule and 'declaration follows usage' for parsing C and C++ declarations
You just have to build it up in steps.
char *X(); // X =~ (*(*a[N])())
Function returning char*
char *(*Y())(); // Y =~ (*a[N])
Function returning pointer to function returning char*
.
In a declaration, just as in an expression (declaration follow usage), postfix []
has a higher precedence that unary *
so *a[N]
is equivalent to *(a[N])
, not (*a)[N]
.
char *(*(*Z)())(); // Z =~ a[N]
Pointer to function returning pointer to function returning char*
.
char *(*(*a[N])())();
Array of N pointers to functions returning a pointer to function returning char*
.
Complex declarations
Here is a great article about how to read complex declarations in C: http://www.codeproject.com/KB/cpp/complex_declarations.aspx
It helped me a lot!
Especially - You should read "The right rule" section. Here quote:
int * (* (*fp1) (int) ) [10];
This can be interpreted as follows:
- Start from the variable name -------------------------- fp1
- Nothing to right but ) so go left to find * -------------- is a pointer
- Jump out of parentheses and encounter (int) --------- to a
function that takes an int as argument- Go left, find * ---------------------------------------- and returns a pointer
- Jump put of parentheses, go right and hit [10] -------- to an array of
10- Go left find * ----------------------------------------- pointers to
- Go left again, find int -------------------------------- ints.
Complex C declaration
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();
How do read this C++ statement
topval( ) // topval is a member function...
const; // In which *this is const...
const Stock &s // Taking in a reference
// to a const Stock...
const Stock & // And returning a reference
// to a const Stock.
Related Topics
Initializer List Not Working with Vector in Visual Studio 2012
Copy Elision: Move Constructor Not Called When Using Ternary Expression in Return Statement
How to Use Sort() in C++ with Custom Sort Member Function
How Would You Implement a Basic Event-Loop
Generating a Normal Map from a Height Map
Compiling Qt 4.8.X for Visual Studio 2012
How to Create a Dll with Swig from Visual Studio 2010
Determining Exception Type After the Exception Is Caught
Differencebetween a MACro and a Const in C++
Understanding the Dangers of Sprintf(...)
How to Cast a Derived Class to a Private Base Class, Using C-Style Cast
How to (Un)Escape Strings in C/C++
How to Find a Search Term in Source Code
Compiling with G++ Using Multiple Cores
Why Should I Ever Use Inline Code
What Is a Scalar Object in C++