Why is constness not enforced for pointers?
Clash Royale CLAN TAG#URR8PPP
up vote
11
down vote
favorite
Consider the following code snippet:
class A
public:
void nonConstFun()
;
class B
private:
A a_;
A * pA_;
public:
void fun() const
pA_->nonConstFun();
//a_.nonConstFun(); // Gives const related error
;
int main()
B b;
b.fun();
Here I am expecting the compiler to fail the compilation for lack of constness for calling A::nonConstFun()
inside B::fun()
irrespective of the type of A object.
However the compiler complains for the object, but not for the pointer. Why?
I am using VS2017 on Windows 10.
c++ pointers const
add a comment |Â
up vote
11
down vote
favorite
Consider the following code snippet:
class A
public:
void nonConstFun()
;
class B
private:
A a_;
A * pA_;
public:
void fun() const
pA_->nonConstFun();
//a_.nonConstFun(); // Gives const related error
;
int main()
B b;
b.fun();
Here I am expecting the compiler to fail the compilation for lack of constness for calling A::nonConstFun()
inside B::fun()
irrespective of the type of A object.
However the compiler complains for the object, but not for the pointer. Why?
I am using VS2017 on Windows 10.
c++ pointers const
add a comment |Â
up vote
11
down vote
favorite
up vote
11
down vote
favorite
Consider the following code snippet:
class A
public:
void nonConstFun()
;
class B
private:
A a_;
A * pA_;
public:
void fun() const
pA_->nonConstFun();
//a_.nonConstFun(); // Gives const related error
;
int main()
B b;
b.fun();
Here I am expecting the compiler to fail the compilation for lack of constness for calling A::nonConstFun()
inside B::fun()
irrespective of the type of A object.
However the compiler complains for the object, but not for the pointer. Why?
I am using VS2017 on Windows 10.
c++ pointers const
Consider the following code snippet:
class A
public:
void nonConstFun()
;
class B
private:
A a_;
A * pA_;
public:
void fun() const
pA_->nonConstFun();
//a_.nonConstFun(); // Gives const related error
;
int main()
B b;
b.fun();
Here I am expecting the compiler to fail the compilation for lack of constness for calling A::nonConstFun()
inside B::fun()
irrespective of the type of A object.
However the compiler complains for the object, but not for the pointer. Why?
I am using VS2017 on Windows 10.
c++ pointers const
c++ pointers const
edited 9 mins ago


Boann
35.8k1285116
35.8k1285116
asked 2 hours ago
Arun
1,15621431
1,15621431
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
15
down vote
accepted
It is enforced.
If you try changing the pointer, the compiler will not let you.
The thing that the pointer points to, however, is a different conversation.
Remember, T* const
and T const*
are not the same thing!
You can protect that by either actually making it A const*
, or simply by writing your function in the manner that is appropriate.
3
I think the question is why doesn't the function'sconst
qualifier protect pointed to objects just as much as the pointer itself. Unfortunately if you makeA const*
then non const functions can't modify the object. This is a known "flaw/feature" ofC++
. Although the "why" of it is probably too "opinion" based forSO
.
– Galik
2 hours ago
3
@Galik the why is explained byT* const
andT const*
are not the same thing!. As for the "flaw" - it's not a flaw. It's up to the programmer to decide if the object pointed by the pointer is logically inside the objectB
or if it logically external, because physically it is external. Modifying the*pa
doesn't modify the objectB
in any physical way. The shortcoming ofC++
is that it doesn't offer an easy way to represent a logicial belonging, which is in the process of fixing withpropagate_const
.
– bolov
2 hours ago
@bolov I think your comment to me here is the closest we have so far to actually answering the question. I already upvoted your answer for the new information it provided but it might be worth copying some of the substance (the design trade-offs) from your comment to me into your answer?
– Galik
2 hours ago
@Galik ok, done
– bolov
1 hour ago
add a comment |Â
up vote
19
down vote
The other answers explain the T* const
vs T const
which is what is happening. But it important to understand the implication of this beyond just the mere syntax.
When you have a T*
inside a structure the pointer is inside the object, but the pointed object is physically outside of the struct. That is why for a const object with a T*
member it not allowed to modify the pointer, but it is allowed to modify the pointed object - because physically the pointed object is outside the enclosing object.
And it is up to the programmer to decide if the pointed object is logically part of the enclosing object (and as such should share constness with the enclosing) or if it is logically an external entity.
The shortcoming of C++ is that it doesn't offer an easy way to express a logical constness as stated above (what you actually expected from your code).
This is known and for this exact purpose there is an experimental class which is not yet standard propagate_const
std::experimental::propagate_const is a const-propagating wrapper for
pointers and pointer-like objects. It treats the wrapped pointer as a
pointer to const when accessed through a const access path, hence the
name.
struct B
A a_;
std::experimental::propagate_const<A *> pA_;
void fun()
pA_->nonConstFun(); // OK
void fun() const
// pA_->nonConstFun(); // compilation error
;
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
15
down vote
accepted
It is enforced.
If you try changing the pointer, the compiler will not let you.
The thing that the pointer points to, however, is a different conversation.
Remember, T* const
and T const*
are not the same thing!
You can protect that by either actually making it A const*
, or simply by writing your function in the manner that is appropriate.
3
I think the question is why doesn't the function'sconst
qualifier protect pointed to objects just as much as the pointer itself. Unfortunately if you makeA const*
then non const functions can't modify the object. This is a known "flaw/feature" ofC++
. Although the "why" of it is probably too "opinion" based forSO
.
– Galik
2 hours ago
3
@Galik the why is explained byT* const
andT const*
are not the same thing!. As for the "flaw" - it's not a flaw. It's up to the programmer to decide if the object pointed by the pointer is logically inside the objectB
or if it logically external, because physically it is external. Modifying the*pa
doesn't modify the objectB
in any physical way. The shortcoming ofC++
is that it doesn't offer an easy way to represent a logicial belonging, which is in the process of fixing withpropagate_const
.
– bolov
2 hours ago
@bolov I think your comment to me here is the closest we have so far to actually answering the question. I already upvoted your answer for the new information it provided but it might be worth copying some of the substance (the design trade-offs) from your comment to me into your answer?
– Galik
2 hours ago
@Galik ok, done
– bolov
1 hour ago
add a comment |Â
up vote
15
down vote
accepted
It is enforced.
If you try changing the pointer, the compiler will not let you.
The thing that the pointer points to, however, is a different conversation.
Remember, T* const
and T const*
are not the same thing!
You can protect that by either actually making it A const*
, or simply by writing your function in the manner that is appropriate.
3
I think the question is why doesn't the function'sconst
qualifier protect pointed to objects just as much as the pointer itself. Unfortunately if you makeA const*
then non const functions can't modify the object. This is a known "flaw/feature" ofC++
. Although the "why" of it is probably too "opinion" based forSO
.
– Galik
2 hours ago
3
@Galik the why is explained byT* const
andT const*
are not the same thing!. As for the "flaw" - it's not a flaw. It's up to the programmer to decide if the object pointed by the pointer is logically inside the objectB
or if it logically external, because physically it is external. Modifying the*pa
doesn't modify the objectB
in any physical way. The shortcoming ofC++
is that it doesn't offer an easy way to represent a logicial belonging, which is in the process of fixing withpropagate_const
.
– bolov
2 hours ago
@bolov I think your comment to me here is the closest we have so far to actually answering the question. I already upvoted your answer for the new information it provided but it might be worth copying some of the substance (the design trade-offs) from your comment to me into your answer?
– Galik
2 hours ago
@Galik ok, done
– bolov
1 hour ago
add a comment |Â
up vote
15
down vote
accepted
up vote
15
down vote
accepted
It is enforced.
If you try changing the pointer, the compiler will not let you.
The thing that the pointer points to, however, is a different conversation.
Remember, T* const
and T const*
are not the same thing!
You can protect that by either actually making it A const*
, or simply by writing your function in the manner that is appropriate.
It is enforced.
If you try changing the pointer, the compiler will not let you.
The thing that the pointer points to, however, is a different conversation.
Remember, T* const
and T const*
are not the same thing!
You can protect that by either actually making it A const*
, or simply by writing your function in the manner that is appropriate.
answered 2 hours ago


Lightness Races in Orbit
272k48436748
272k48436748
3
I think the question is why doesn't the function'sconst
qualifier protect pointed to objects just as much as the pointer itself. Unfortunately if you makeA const*
then non const functions can't modify the object. This is a known "flaw/feature" ofC++
. Although the "why" of it is probably too "opinion" based forSO
.
– Galik
2 hours ago
3
@Galik the why is explained byT* const
andT const*
are not the same thing!. As for the "flaw" - it's not a flaw. It's up to the programmer to decide if the object pointed by the pointer is logically inside the objectB
or if it logically external, because physically it is external. Modifying the*pa
doesn't modify the objectB
in any physical way. The shortcoming ofC++
is that it doesn't offer an easy way to represent a logicial belonging, which is in the process of fixing withpropagate_const
.
– bolov
2 hours ago
@bolov I think your comment to me here is the closest we have so far to actually answering the question. I already upvoted your answer for the new information it provided but it might be worth copying some of the substance (the design trade-offs) from your comment to me into your answer?
– Galik
2 hours ago
@Galik ok, done
– bolov
1 hour ago
add a comment |Â
3
I think the question is why doesn't the function'sconst
qualifier protect pointed to objects just as much as the pointer itself. Unfortunately if you makeA const*
then non const functions can't modify the object. This is a known "flaw/feature" ofC++
. Although the "why" of it is probably too "opinion" based forSO
.
– Galik
2 hours ago
3
@Galik the why is explained byT* const
andT const*
are not the same thing!. As for the "flaw" - it's not a flaw. It's up to the programmer to decide if the object pointed by the pointer is logically inside the objectB
or if it logically external, because physically it is external. Modifying the*pa
doesn't modify the objectB
in any physical way. The shortcoming ofC++
is that it doesn't offer an easy way to represent a logicial belonging, which is in the process of fixing withpropagate_const
.
– bolov
2 hours ago
@bolov I think your comment to me here is the closest we have so far to actually answering the question. I already upvoted your answer for the new information it provided but it might be worth copying some of the substance (the design trade-offs) from your comment to me into your answer?
– Galik
2 hours ago
@Galik ok, done
– bolov
1 hour ago
3
3
I think the question is why doesn't the function's
const
qualifier protect pointed to objects just as much as the pointer itself. Unfortunately if you make A const*
then non const functions can't modify the object. This is a known "flaw/feature" of C++
. Although the "why" of it is probably too "opinion" based for SO
.– Galik
2 hours ago
I think the question is why doesn't the function's
const
qualifier protect pointed to objects just as much as the pointer itself. Unfortunately if you make A const*
then non const functions can't modify the object. This is a known "flaw/feature" of C++
. Although the "why" of it is probably too "opinion" based for SO
.– Galik
2 hours ago
3
3
@Galik the why is explained by
T* const
and T const*
are not the same thing!. As for the "flaw" - it's not a flaw. It's up to the programmer to decide if the object pointed by the pointer is logically inside the object B
or if it logically external, because physically it is external. Modifying the *pa
doesn't modify the object B
in any physical way. The shortcoming of C++
is that it doesn't offer an easy way to represent a logicial belonging, which is in the process of fixing with propagate_const
.– bolov
2 hours ago
@Galik the why is explained by
T* const
and T const*
are not the same thing!. As for the "flaw" - it's not a flaw. It's up to the programmer to decide if the object pointed by the pointer is logically inside the object B
or if it logically external, because physically it is external. Modifying the *pa
doesn't modify the object B
in any physical way. The shortcoming of C++
is that it doesn't offer an easy way to represent a logicial belonging, which is in the process of fixing with propagate_const
.– bolov
2 hours ago
@bolov I think your comment to me here is the closest we have so far to actually answering the question. I already upvoted your answer for the new information it provided but it might be worth copying some of the substance (the design trade-offs) from your comment to me into your answer?
– Galik
2 hours ago
@bolov I think your comment to me here is the closest we have so far to actually answering the question. I already upvoted your answer for the new information it provided but it might be worth copying some of the substance (the design trade-offs) from your comment to me into your answer?
– Galik
2 hours ago
@Galik ok, done
– bolov
1 hour ago
@Galik ok, done
– bolov
1 hour ago
add a comment |Â
up vote
19
down vote
The other answers explain the T* const
vs T const
which is what is happening. But it important to understand the implication of this beyond just the mere syntax.
When you have a T*
inside a structure the pointer is inside the object, but the pointed object is physically outside of the struct. That is why for a const object with a T*
member it not allowed to modify the pointer, but it is allowed to modify the pointed object - because physically the pointed object is outside the enclosing object.
And it is up to the programmer to decide if the pointed object is logically part of the enclosing object (and as such should share constness with the enclosing) or if it is logically an external entity.
The shortcoming of C++ is that it doesn't offer an easy way to express a logical constness as stated above (what you actually expected from your code).
This is known and for this exact purpose there is an experimental class which is not yet standard propagate_const
std::experimental::propagate_const is a const-propagating wrapper for
pointers and pointer-like objects. It treats the wrapped pointer as a
pointer to const when accessed through a const access path, hence the
name.
struct B
A a_;
std::experimental::propagate_const<A *> pA_;
void fun()
pA_->nonConstFun(); // OK
void fun() const
// pA_->nonConstFun(); // compilation error
;
add a comment |Â
up vote
19
down vote
The other answers explain the T* const
vs T const
which is what is happening. But it important to understand the implication of this beyond just the mere syntax.
When you have a T*
inside a structure the pointer is inside the object, but the pointed object is physically outside of the struct. That is why for a const object with a T*
member it not allowed to modify the pointer, but it is allowed to modify the pointed object - because physically the pointed object is outside the enclosing object.
And it is up to the programmer to decide if the pointed object is logically part of the enclosing object (and as such should share constness with the enclosing) or if it is logically an external entity.
The shortcoming of C++ is that it doesn't offer an easy way to express a logical constness as stated above (what you actually expected from your code).
This is known and for this exact purpose there is an experimental class which is not yet standard propagate_const
std::experimental::propagate_const is a const-propagating wrapper for
pointers and pointer-like objects. It treats the wrapped pointer as a
pointer to const when accessed through a const access path, hence the
name.
struct B
A a_;
std::experimental::propagate_const<A *> pA_;
void fun()
pA_->nonConstFun(); // OK
void fun() const
// pA_->nonConstFun(); // compilation error
;
add a comment |Â
up vote
19
down vote
up vote
19
down vote
The other answers explain the T* const
vs T const
which is what is happening. But it important to understand the implication of this beyond just the mere syntax.
When you have a T*
inside a structure the pointer is inside the object, but the pointed object is physically outside of the struct. That is why for a const object with a T*
member it not allowed to modify the pointer, but it is allowed to modify the pointed object - because physically the pointed object is outside the enclosing object.
And it is up to the programmer to decide if the pointed object is logically part of the enclosing object (and as such should share constness with the enclosing) or if it is logically an external entity.
The shortcoming of C++ is that it doesn't offer an easy way to express a logical constness as stated above (what you actually expected from your code).
This is known and for this exact purpose there is an experimental class which is not yet standard propagate_const
std::experimental::propagate_const is a const-propagating wrapper for
pointers and pointer-like objects. It treats the wrapped pointer as a
pointer to const when accessed through a const access path, hence the
name.
struct B
A a_;
std::experimental::propagate_const<A *> pA_;
void fun()
pA_->nonConstFun(); // OK
void fun() const
// pA_->nonConstFun(); // compilation error
;
The other answers explain the T* const
vs T const
which is what is happening. But it important to understand the implication of this beyond just the mere syntax.
When you have a T*
inside a structure the pointer is inside the object, but the pointed object is physically outside of the struct. That is why for a const object with a T*
member it not allowed to modify the pointer, but it is allowed to modify the pointed object - because physically the pointed object is outside the enclosing object.
And it is up to the programmer to decide if the pointed object is logically part of the enclosing object (and as such should share constness with the enclosing) or if it is logically an external entity.
The shortcoming of C++ is that it doesn't offer an easy way to express a logical constness as stated above (what you actually expected from your code).
This is known and for this exact purpose there is an experimental class which is not yet standard propagate_const
std::experimental::propagate_const is a const-propagating wrapper for
pointers and pointer-like objects. It treats the wrapped pointer as a
pointer to const when accessed through a const access path, hence the
name.
struct B
A a_;
std::experimental::propagate_const<A *> pA_;
void fun()
pA_->nonConstFun(); // OK
void fun() const
// pA_->nonConstFun(); // compilation error
;
edited 1 hour ago
answered 2 hours ago
bolov
28.1k664121
28.1k664121
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52607625%2fwhy-is-constness-not-enforced-for-pointers%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password