This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Declaring pointers; asterisk on the left or right of the space between the type and name?
I've always been wondering what's the exact correct position to put * and &. it seems that C++ is pretty tolerant about where to put these marks.
For example I've seem pointer and ampersand been put on both left and right of a keyword or in the middle of two keywords, but confusingly sometimes they seems to mean the same thing, especially when used together with const
void f1(structure_type const& parameter)
void f2(structure_type const ¶meter)
void f2(structure_type const *sptr);
void f2(structure_type const* sptr);
void f2(structure_type const * sptr);
The examples are not exhaustive. I see them everywhere while being declared or been passed to a function. Do they even mean the same thing? But I also see cases while putting * will affect which object being referred as a pointer (likely the case where * is in between two keywords).
EDITED:
int const *Constant
int const * Constant // this above two seem the same to me, both as pointer to a constant value
int const* Constant // EDIT: this one seems the same as above. instead of a constant pointer
const int * Constant // this is also a pointer to a constant value, but the word order changed while the pointer position stays the same, rather confusing.
int* const Constant
int * const Constant // instead, these two are constant pointers
So I concluded this:
T const* p; // pointer to const T
const T* p // seems same from above
T* const p; // const pointer to T
Still, this confused the hell out of me. Doesn't the compiler care about position and the spacing required for them?
Edit:
I want to know in general of the position matters. If yes in what cases.
White space matters only to the degree that it keeps tokens from running together and (for example) creating a single token, so (for example) int x is obviously different from intx.
When you're dealing with something like: int const*x;, whitespace on either size of the * makes absolutely no difference to the compiler at all.
The difference between a pointer to const int and const pointer to int depends on which side of the * the const is on.
int const *x; // pointer to const int
int *const x; // const pointer to int
The primary difference is readability when/if you define/declare multiple objects in the same declaration.
int* x, y;
int *x, y;
In the first, somebody might think that x and y are pointers to int -- but in fact, x is a pointer to an int, and y is an int. To some people's eyes, the second reflects that fact more accurately.
One way to prevent any misinterpretation is to only ever define one object at a time:
int *x;
int y;
For any of these, correct interpretation is fairly easy if you ignore whitespace entirely (except to tell you where one toke ends and another starts, so you know "const int" is two tokens) and read from right to left, reading * as "pointer to". For example: int volatile * const x; is read as "x is a const pointer to a volatile int".
int const *Constant
int const * Constant
int const* Constant
All of the above intend to declare a non constant pointer to a constant integer.
Simple rule:
If const follows after the * it applies to the pointer if not it applies to the pointed object. The spacing doesn't matter.
Both & and * placements in variable declaration are acceptable and only depends on your own flavour. They strictly mean the same thing, creating respectively a pointer and a reference.
However, the const keyword placement is primordial, as a int const* variable declares a constant pointer to a non-constant int, and const int* variable is a non-constant pointer to a constant int.
Related
i'd like to know if there is a sort of implicit conversion between variables when using a pointer to constant integer ,
for example , if i use an address of a variable type int or const int it accepts to store it ,
however if i use a normal pointer to int it doesn't allow storing the address of the const int type,why is this?, thanks in advance
int i=4;
const int ii=4;
//pointer to constant int
const int *pci=&i; //OK.
pci=ⅈ //OK.
int *pi=ⅈ //ERROR invalid conversion.
The first and second assignments initialize pci to constly point to an int or a const int.
So you might have one of two situations:
const int* which points to an int.
pci=&i;
const int* which points to a const int.
pci=ⅈ
Both cases are safe because you are only adding a constraint.
By doing:
int *pi=ⅈ
You make an int* point to a const int which means you remove a constraint.
Since removing a constraint might be risky, this requires you to use a const_cast.
int* pi = const_cast<int*>(&ii);
Note that forcibly removing the const modifier is something you should ask yourself twice if you really wanna do, since it also make the const modifier somewhat meaningless because you will be able to modify that "constant" address through the converted variable.
Simply assigning a pointer to a const element to a pointer to a non-const element is not allowed, since that would silently dismiss the const-ness of the original, which is something that you don't want, and can also be a source of silent bugs, which is one of the reasons it's not allowed.
However, if this is really what you want, you can explicitly request to remove the const qualifier by using const_cast
I am learning C++. In my course, it is explained that it is best to place const immediately after the thing you want to make unchangeable, because this is how const works.
Many people, including for instance Bjarne Stroustrup himself, like to write const in front. But this sometimes leads to problems:
const int *foo; //modifiable pointer to a constant int.
int const *bar; //constant pointer to a modifiable int? No! It's a modifiable pointer to a constant int. (So the same type as foo)
An example that shows this in action:
int fun(int const *mypointer)
{
*mypointer = 5; //Won't compile, because constant int.
mypointer = 0; // Is okay, because modifiable pointer.
}
What makes this even more confusing, is that compilers such as g++ like to rewrite int const bar to const int bar in their error messages.
Now, this behaviour is confusing me greatly. Why does const work in this way? It would seem a lot easier to understand if it would 'just' work on the thing put after it.
C++ follows syntax of C.
It looks weird, but in C you specify not a type of variable, but a type of expression with it:
int v means that v is int;
int *v means that *v is int, so v is pointer to int;
int v[] means that v[…] is int, so v is array of int;
int v() means that v() is int, so v is function returning int;
etc (you always need to read such declaration from inner).
More closely to your question, in C type specification can consist of several words: unsigned char, long int, const double (even more than two — const unsigned long long int). Number of repeated words matters (long long int in general case is different from long int), but order of words doesn't (long int is the same as int long). That's why const int *p is the same as int const *p (as well as const int i is the same as int const i).
As for int * const p, it probably doesn't obey common scheme. As there is no such expression as * const p (where p is a variable) in C, so we can't explain it with something like "expression * const p will have type int". However, think, where else can we put const keyword to specify that pointer itself is constant, not its dereferenced value? (Assuming that both const int *p and int const *p mean that a dereferenced value is constant, and we don't want to introduce additional keywords into language.) Nowhere except after *; so here it goes.
To understand a C declaration there is a Right-Left rule that is very helpful: For example
int *
is a pointer to an integer (note that you have to read that right to left). Same thing for reference to int:
int &
Now read the type of p8 from right to left:
char * const * const p8; // const pointer to const pointer to char
I suspect that const modifies the preceding type, just to be consistent with that rule. The fact that you can put const in the very beginning of the declaration is an exception.
Note: the example comes from this article (but I changed it slightly).
I am having trouble finding an intuitive pattern for the way const is used in declarations in the C and C++ languages. Here are some examples:
const int a; //Const integer
int const a; //Const integer
const int * a; //Pointer to constant integer
int * const a; //Const pointer to an integer
int const * a const; //Const pointer to a const integer
In lines 1 and 2, it seems const can come before or after int, which is what it modifies.
So how, in line 4, does the compiler decide that const is modifying * (pointer) rather than int?
What is the rule that the compiler follows for deciding which thing the const applies to?
Does it follow the same rule for *?
Assuming you always place const to the right of the type, you can read a variable declaration as a sentence from right to left:
int const x; // x is a constant int
int *const x; // x is a constant pointer to an int
int const *x; // x is a pointer to a constant int
int const *const x; // x is a constant pointer to a constant int
This still works if you put const to the left of a type, but requires a bit more mental effort. Note that this works just as well with pointers-to-pointers (and higher order constructs):
int *const *const x; // x is a constant pointer to a constant pointer to an int
The compiler generally reads the type from right-to-left, so:
T const& const
Would be read as:
const (a constant)
& (to a reference)
const (to a constant)
T (of type T)
So, basically the keyword "const" modifies everything that precedes it. However, there is an exception in the case where "const" comes first, in which case it modifies the item directly to the right of it:
const T& const
The above is read as:
const (a constant)
& (to a reference)
const T (to a constant of type T)
And the above is equivalent to T const& const.
While this is how the compiler does it, I really just recommend memorizing the cases "T", "const T", "const T&", "const T*", "const T& const", "const T* const", "T& const", and "T* const". You will rarely encounter any other variation of "const", and when you do, it's probably a good idea to use a typedef.
For pointers, here's one I picked up from one of Scott Meyers's books (I think). Draw a vertical line through the *, and then whatever's on the same side of the line as the const keyword is the thing that's const.
To clarify:
int * const a means that a is const, not the int. And "a" is a pointer to the (non-const) int.
Well, to start off, this question is more of a personal preference. For the leisure programmer, it's more of a personal style. However, for those that deal with corporates, there can be some kind of coding convention that they layout for programmers to follow such that everyone comes out with consistent coding styles.
(1) For const int * const a; it means that you can't change what your pointer points to but you can modify that memory location.
(2) The 'const' is decided by you, as the programmer, whether you want the address the pointer points to, to be constant or if you want the pointer to NOT modify the pointer it points to.
(3) Yes the rules are the same for * as in the case of const int * const a;
As an additional note, your last line is not valid C89.
Hope it helps. Cheers!
The key to understanding these is to realise that the * binds to the a, not to the type. So you should read these as:
const int a; // a has type const int
int const a; // a has type int const
const int * a; // *a has type const int
int * const a; // *(const a) has type int, which means *a has type int and a is const
int const * a const; // *(const a) has type int const, which means *a has type const int and a is const.
(Note though that C++ references do not follow this rule).
To start you probably know that const can be used to make either an object's data or a pointer not modifiable or both.
const Object* obj; // can't change data
Object* const obj; // can't change pointer
const Object* const obj; // can't change data or pointer
However you can also use the syntax:
Object const *obj; // same as const Object* obj;
The only thing that seems to matter is which side of the asterisk you put the const keyword. Personally I prefer to put const on the left of the type to specify it's data is not modifiable as I find it reads better in my left-to-right mindset but which syntax came first?
More importantly why is there two correct ways of specifying const data and in what situation would you prefer or need one over the other if any?
Edit:
So it sounds like this was an arbitrary decision when the standard for how compilers should interpret things was drafted long before I was born. Since const is applied to what is to the left of the keyword (by default?) I guess they figured there was no harm in adding "shortcuts" to apply keywords and type qualifiers in other ways at least until such a time as the declaration changes by parsing a * or & ...
This was the case in C as well then I'm assuming?
why is there two correct ways of specifying const data and in what situation would you prefer or need one over the other if any?
Essentially, the reason that the position of const within specifiers prior to an asterisk does not matter is that the C grammar was defined that way by Kernighan and Ritchie.
The reason they defined the grammar in this way was likely that their C compiler parsed input from left-to-right and finished processing each token as it consumed that. Consuming the * token changes the state of the current declaration to a pointer type. Encountering const after * means the const qualifier is applied to a pointer declaration; encountering it prior to the * means the qualifier is applied to the data pointed to.
Because the semantic meaning does not change if the const qualifier appears before or after the type specifiers, it is accepted either way.
A similar sort of case arises when declaring function pointers, where:
void * function1(void) declares a function which returns void *,
void (* function2)(void) declares a function pointer to a function which returns void.
Again the thing to notice is that the language syntax supports a left-to-right parser.
The rule is:
const applies to the thing left of it. If there is nothing on the left then it applies to the thing right of it.
I prefer using const on the right of the thing to be const just because it is the "original" way const is defined.
But I think this is a very subjective point of view.
I prefer the second syntax. It helps me keep track of 'what' is constant by reading the type declaration from right to left:
Object * const obj; // read right-to-left: const pointer to Object
Object const * obj; // read right-to-left: pointer to const Object
Object const * const obj; // read right-to-left: const pointer to const Object
The order of the keywords in a declaration isn't all that fixed. There are many alternatives to "the one true order". Like this
int long const long unsigned volatile i = 0;
or should it be
volatile unsigned long long int const i = 0;
??
The first rule is to use whichever format your local coding standards
requires. After that: putting the const in front leads to no end of
confusion when typedefs are involved, e.g.:
typedef int* IntPtr;
const IntPtr p1; // same as int* const p1;
If your coding standard allows typedef's of pointers, then it really
should insist on putting the const after the type. In every case but
when applied to the type, const must follow what it applies to, so
coherence also argues in favor of the const after. But local coding
guidelines trump all of these; the difference isn't normally important
enough to go back and change all of the existing code.
There are historical reasons that either left or right is acceptable. Stroustrup had added const to C++ by 1983, but it didn't make it to C until C89/C90.
In C++ there's a good reason to always use const on the right. You'll be consistent everywhere because const member functions must be declared this way:
int getInt() const;
C uses a right-to-left syntax. Just read the declarations from right to left:
int var = 0;
// one is a pointer to a const int
int const * one = &var;
// two is a pointer to an int const (same as "const int")
const int * two = &var;
// three is a constant pointer to an int
int * const three = &var;
The first thing left to the "const" is affected by it.
For more fun read this guide:
http://cseweb.ucsd.edu/~ricko/rt_lt.rule.html
With
using P_Int = int *;
P_Int const a = nullptr;
int * const b = nullptr;
const P_Int c = nullptr;
const int * d = nullptr;
the variables a and b are the same type as each other but, somewhat confusingly, the variables c and d are not the same type as each other. My preference is for the first scenario, without the confusion: have const on the right of the type. N.B. it is the pointer that is const with a, b, and c; but the int is const with d.
When I work with the existing code, I follow the way already being used which is most of the time, const on left e.g const int a = 10; but if I got a chance to work from start I choose the "right way", means const on right e.g int const a = 10;, which is a more universal approach and straightforward to read.
As mentioned already, the rule is
const applies to the thing left of it. If there is nothing on the left then it applies to the thing right of it.
Here is the example code for basic use cases.
int main() {
int const a = 10; // Constant integer
const int b = 20; // Constant integer (same as above)
int c = 30; // Integer (changeable)
int * const d = &c; // Constant pointer to changeable integer
int const * e = &a; // Changeable pointer to constant integer
int const * const f = &a; // Constant pointer to constant integer
return 0;
}
At the end of the day, if there is no guideline to follow, this is subjective, and harmless to use either approach.
i have a class name X, what is the difference between "const X a" and "X const a"
Nothing.
A const qualifier applies to whatever is immediately to its left. If there is nothing to its left then it applies to whatever is immediately to its right.
In this case, there's no difference at all.
When you have a pointer or a reference, a change that might look almost the same is significant though. Given something like:
T * a;
The position of const (or volatile) relative to the asterisk is significant:
T const * a;
T * const a;
The first one says that a is a pointer to a const T (i.e., you can't modify the T object that a refers to). The second one says that a is a const point to a (non-const) T -- i.e., you can modify what a points at, but you can't modify the pointer itself, so you can't point it at a different object. Of course, you can also do both:
T const * const a;
This means you can't change the pointer itself or the T object it refers to.
If you use simple types (embedded or custom) then that is a matter of taste.
In case of using pointers there is a simple general rule: if const is placed before '*' then the data pointed is constant and otherwise the pointer itself is constant, you can't change its value.
For example:
const int a=1; // 'a' value can't be changed
const int* q; // the data that 'a' point to is constant
int const* q; // the same
int* const p=&a; // the pointer is constant: const is behind '*'
so
int b=2;
p = &b; // error: trying to change constant pointer