Declaration of pointers in C++ - c++

In C++ whats the difference between
char const *ptr=&ch;
and
const char *ptr=&ch;

They are the same, i.e. pointer to const char.
However char * const ptr is different, being a const pointer to (non-const) char.
And just to complete the set, const char * const ptr is a const pointer to const char.

No difference in C++.
It is important const is before * or after *.

Const applies to whatever is on its immediate left (other than if there is nothing there in which case it applies to whatever is its immediate right). So there is no difference.
char * const ptr would be a const pointer to variable value though.

Other answers have covered the technical solution - your two examples are the same.
Many people prefer to read from right to left when dealing with const in C++. In English, we like to think of a constant X, while C++ likes to parse an X const. Reading right to left yields a more English result.
A rather extreme example:
C const * bar(A * const, B const * const) const;
From right to left this reads as 'A constant function bar taking as parameters a constant pointer to an A and a constant pointer to a constant B, returning a pointer to a constant C'. Note that all three kinds of pointers are different.

char const *ptr=&ch; and const char *ptr=&ch; means char is const, where as the pointer is variable (or it can be changed).
But In case of char * const ptr, you cannot re-assign the pointer once you set it. so its a const pointer to a char string.

Related

My pointers are causing "same type qualifier used more than once" warnings?

From what I understood about using the const type qualifier with a pointer, is that it depends where you use it.
const MyType *
Would mean that the location cannot be modified, but the value at the location can.
MyType const *
Would mean that the location can be modified, but not the value at the location.
From this, I would seen no reason for the following not to be valid,
const MyType const *
To define a pointer whose location is fixed, and for which the value pointed to cannot be modified. However, this is throwing "same type qualifier used more than once." Should I ignore this? Is my understanding of const semantics in the context of pointers flawed?
You are slightly mistaken about the syntax. In fact
const MyType *
and
MyType const *
mean the same thing: the underlying MyType object is constant. The syntax for making the pointer itself constant is:
MyType * const
Thus if you want both to be constant, you would use:
MyType const * const
Or:
const MyType * const
A way to remember this is: the thing which is constant is the thing immediately to the left of the keyword const (which is * for pointer or MyType for the object), unless there is nothing to the left: in which case it is the thing to the right.
const MyType * and MyType const * are the same thing. They both mean pointer to const, i.e. the pointee is const. So for const MyType const *, you'll get the error because the const qualifier is used twice for the same thing.
What you want might be MyType const * const(note the position of const and *), which is a const pointer to const, i.e. the pointer itself and the pointee are both const. You could read it from right to left as "const pointer to const MyType".

C++ constructor with a const argument

I just wondered what's the difference between having a constructor with const char* c or char* const c as a parameter?
If I swap char* and const in header and source file it isn't a problem but when I mix them it won't compile, saying there is no such overloaded constructor.
When I use my own class for a copy constructor the compiler doesn't seem to bother if I have MyClass const &other and const MyClass &other mixed..
Can anyone enlighten me please? :)
This record const char *c declares pointer c that points to an object of type const char. That is using this pointer you may not change the object that refered to by the pointer.
This record char * const c declares const pointer c that points to a non-const object of type char. You may not change the pointer itself but you may change the object refered to by the pointer.
There is a difference between declaring pointers and references. Though there is used term "constant reference" strictly speaking references themselves may not be constant. According to the C++ grammar
ptr-operator:
* attribute-specifier-seqopt cv-qualifier-seq
& attribute-specifier-seqopt
references do not contain cv-qualifier-seq. So for example this record
Airplane & const other
will be incorrect and the compiler shall issue an error.
As for these records
const Airplane & other
Airplane const & other
then they are equivalent the same way as equivalent the recirds below
const char *c
char const *c
Think of the * as a "fence". What's before it in the declaration defines the type that the pointer refers to. What's after the * defines the pointer itself. For this case, it's easiest to read things backwards (translating * as "pointer to"), so char const *t is read (from back to front) as: "t is a pointer to a const char". Likewise, char *const t is read as: "t is a const pointer to a char."
char *const means the pointer itself is const (can't be modified), but the char(s) it points at can be modified.
char const * or const char * are equivalent to each other. Both mean the pointer itself can be modified, but what it points at cannot.
Substituting a different type for char doesn't change that basic idea.
The same is true with a reference: const T & means a reference to a const T, so you can't modify the T that it refers to. In the case of a reference, you can't modify the reference itself to refer to a different object, so T & const doesn't make any real sense (and isn't allowed).
const applies to the type to its left (or to its right if there is nothing on its left), so const char * and char const * are the same and mean that the characters cannot change, but the pointer can, whereas char * const means that the characters can change but the pointer cannot
The order in which const and char* are written actually make a difference. If you have const char* in your header but char* const in your source file, you will get an error because the compiler won't regard these as the same.
const char* p means that p points to a char that is constant. We can alter where p points to, but we can never alter the contents stored at p.
char* const p means that p is a constant pointer and is pointing to a char. We can alter the contents stored at p, but we cannot alter where p points to.
const char* const p means that p is a constant pointer to a constant char. We cannot alter where p points to nor can we alter the contents at p. Hope this is helpful!

pointer and ampersand position with const in C++ [duplicate]

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 &parameter)
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.

Making sense of where "const" goes in a declaration

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).

Double const declaration

I often see the following function declaration:
some_func(const unsigned char * const buffer)
{
}
Any idea why the const is repeated before the pointer name?
Thanks.
The first const says that the data pointed to is constant and may not be changed whereas the second const says that the pointer itself may not be changed:
char my_char = 'z';
const char* a = &my_char;
char* const b = &my_char;
const char* const c = &my_char;
a = &other_char; //fine
*a = 'c'; //error
b = &other_char; //error
*b = 'c'; //fine
c = &other_char; //error
*c = 'c'; //error
type declarations should(?) be read RTL. const modifies the thing on its left, but the rule is complicated by the fact that you can write both const T and T const (they mean the same thing).
T * const is a constant pointer to mutable T
T & const would be constant reference to mutable T, except references are constant by definition
T const * is a mutable pointer to constant T
T const & is a reference to constant T
T const * const is constant pointer to constant T
It's a constant pointer to a constant unsigned char. You can't change the pointer nor the thing it points to.
In a declaration like const * const T, the first const (before the *) means that what the pointer points at is const (i.e. it's a pointer to a const T). The const after the * means that the pointer itself is const (i.e. can't be modified to point at anything else).
You can read the declaration from the object being declared outward, so const unsigned char * const buffer is read as: "buffer is a const pointer to a const unsigned char" (this is why const should always being placed after what it modifies--with it before, you have to rearrange things to make the sentence--with it declared as unsigned char const * const buffer, translation to English is simple and straighforward (or perhaps "straightbackward", since you actually read from right to left in this case).
assuming const unsigned char * const
Everyone is correct that its a const pointer to a const unsigned char.
C++ types read mostly right to left unless there are any modifiers on the far left then these read left to right.
This makes it a const pointer to a const value, rather than a mutable pointer to a const value or a const pointer to a mutable value.
const * unsigned char const buffer means that you cannot modify the pointer buffer nor the memory that buffer points to.
A couple of articles to help you understand const correctness in C++:
Wikipedia
Possibility.com