In C++, make an alias const - c++

I'm a beginner to C++ and I have a question that I want to make sure...I've done pretty of searching online.
Let say I have a class call A and it has a function called Afunction. The function looks like:
// this is pseudocode
void Afunction (const A& a)
{
a.something = a.something +1;
}
My understanding is we have an "pointer-like" thing called 'a' and it's an alias to whatever we pass in. Here we only make sure the alias itself is const, but no guarantee that the value to which it points at won't be changed. In fact, I'm changing it..and I don't get no error.
So my question is, how can I make sure the values that the alias is point to can't be changed? It's much easier to be done if it's pointer other than alias...
Thanks in advance.

If a compiler accepts that code, you should ditch it immediately.
You can't modify a.

A const& (which is unforunately equivalent to const A&) is a reference to a const object.
Similarly, A const* is a pointer to a const object, whilst A * const is a const pointer to an object and A const * const is a *const pointer to a const object`.
The key is to read (and write) your type declarations from right-to-left.

It all depends on what is something.
If you posted the code of class A, it would be easier to explain why you can change something.
In general, you can't modify contents of const A&. But...
something can be static, then const doesn't matter since something doesn't technically belong to the a variable in Afunction.
something can be declared mutable. Sometimes having a member variable that can be changed even when the object is const is beneficial. For example, reference counting.
something may be something completely different, with weird semantics. (as Zyx 2000 pointed out).

Related

const and non-const versions of *static* member functions

I have two versions of the same static member function: one takes a pointer-to-const parameter and that takes a pointer-to-non-const parameter. I want to avoid code duplication.
After reading some stack overflow questions (these were all about non-static member functions though) I came up with this:
class C {
private:
static const type* func(const type* x) {
//long code
}
static type* func(type* x) {
return const_cast<type*>(func(static_cast<const type*>(x)));
}
public:
//some code that uses these functions
};
(I know juggling with pointers is generally a bad idea, but I'm implementing a data structure.)
I found some code in libstdc++ that looks like this:
NOTE: these are not member functions
static type* local_func(type* x)
{
//long code
}
type* func(type* x)
{
return local_func(x);
}
const type* func(const type* x)
{
return local_func(const_cast<type*>(x));
}
In the first approach the code is in a function that takes a pointer-to-const parameter.
In the second approach the code is in a function that takes a pointer-to-non-const parameter.
Which approach should generally be used? Are both correct?
The most important rule is that an interface function (public method, a free function other than one in a detail namespace, etc), should not cast away the constness of its input. Scott Meyer was one of the first to talk about preventing duplication using const_cast, here's a typical example (How do I remove code duplication between similar const and non-const member functions?):
struct C {
const char & get() const {
return c;
}
char & get() {
return const_cast<char &>(static_cast<const C &>(*this).get());
}
char c;
};
This refers to instance methods rather than static/free functions, but the principle is the same. You notice that the non-const version adds const to call the other method (for an instance method, the this pointer is the input). It then casts away constness at the end; this is safe because it knows the original input was not const.
Implementing this the other way around would be extremely dangerous. If you cast away constness of a function parameter you receive, you are taking a big risk in UB if the object passed to you is actually const. Namely, if you call any methods that actually mutate the object (which is very easy to do by accident now that you've cast away constness), you can easily get UB:
C++ standard, section § 5.2.11/7 [const cast]
[ Note: Depending on the type of the object, a write operation through the pointer, lvalue or pointer to data member resulting from a
const_cast that casts away a const-qualifier may produce undefined
behavior. —end note ]
It's not as bad in private methods/implementation functions because perhaps you carefully control how/when its called, but why do it this way? It's more dangerous to no benefit.
Conceptually, it's often the case that when you have a const and non-const version of the same function, you are just passing along internal references of the object (vector::operator[] is a canonical example), and not actually mutating anything, which means that it will be safe either way you write it. But it's still more dangerous to cast away the constness of the input; although you might be unlikely to mess it up yourself, imagine a team setting where you write it the wrong way around and it works fine, and then someone changes the implementation to mutate something, giving you UB.
In summary, in many cases it may not make a practical difference, but there is a correct way to do it that's strictly better than the alternative: add constness to the input, and remove constness from the output.
I have actually only ever seen your first version before, so from my experience it is the more common idiom.
The first version seems correct to me while the second version can result in undefined behavior if (A) you pass an actual const object to the function and (B) the long code writes to that object. Given that in the first case the compiler will tell you if you're trying to write to the object I would never recommend option 2 as it is. You could consider a standalone function that takes/returns const however.

How to pass const pointer in parameter non-const

I have two pointers (const Vec* a and const Vec b)
in a given piece of code, I need to pass these two values​​, which are instantiated during the code, for a function that has no parameter (const Vec *) but only (Vec *).
How could I do this without moving the function definition, but if necessary, what procedure should I take?
//const Vec* from;
//const Vec* at;
Vec* viewVec;
viewVec = Vec::sub( view->at, view->from);
//static Vec* sub(Vec*, Vec*);
Vec* Vec::sub(Vec* a, Vec* b) {
return new Vec(a->x - b->x, a->y - b->y, a->z - b->z);
}
The simplest answer is probably: "don't". If you need to use a Vec * instead of a Vec const *, then declare it that way to begin with.
If this is some third party function that promises not to modify it but for some reason has an aversion to const, then the const_cast solutions that other people listed is your only choice (other than to use a better third-party library).
If the std::vector that the pointer you have points to is actually not const (at its point of declaration), and you just happen to have a std::vector const * that refers to it, then it's 'safe' (but still generally unwise) to use const_cast on it. However, if you modify any variable that was originally declared as being const, then it is undefined behavior. For instance, the compiler may see that you are doing some expensive operation on a std::vector const multiple times, and it's free to cache certain parts of the result because it can assume that it's always dealing with the same thing, so if you change it, you may get incorrect (or even inconsistent) results.
You can use const_cast for this, e.g.
viewVec = Vec::sub(const_cast<Vec*>(view->at), const_cast<Vec*>(view->from));
Whether or not you should is another matter. If you really can't change the signature of the function (which is probably the easiest fix), you can always write a wrapper which contains the dodgy casting - that way, at least the caller doesn't need to do any casting itself:
Vec *Vec::sub(const Vec *a, const Vec *b) {
return sub(const_cast<Vec*>(view->at), const_cast<Vec*>(view->from));
}
const_cast<type>(value) There ya go ;)
As people have mentioned you could use const_cast. The reason you have to be careful doing this is that you might end up modifying something that shouldn't be modified. For exampl, if some object declares a pointer as const it is because it wants to ensure that this pointer cannot change. If you then const_cast the pointer and pass it to another function, the other function could make it point at something new, hence screwing with the original object which tried to protect it.
In particular, what if object A allocated some piece of memory which the const pointer points to. If you then pass the pointer to a function via const_cast and this function deletes the memory, or re-allocs it, then the original piece of memory will exist undeleted.
Hope this helps.

C++: Why is const_cast evil?

I keep hearing this statement, while I can't really find the reason why const_cast is evil.
In the following example:
template <typename T>
void OscillatorToFieldTransformer<T>::setOscillator(const SysOscillatorBase<T> &src)
{
oscillatorSrc = const_cast<SysOscillatorBase<T>*>(&src);
}
I'm using a reference, and by using const, I'm protecting my reference from being changed. On the other hand, if I don't use const_cast, the code won't compile. Why would const_cast be bad here?
The same applies to the following example:
template <typename T>
void SysSystemBase<T>::addOscillator(const SysOscillatorBase<T> &src)
{
bool alreadyThere = 0;
for(unsigned long i = 0; i < oscillators.size(); i++)
{
if(&src == oscillators[i])
{
alreadyThere = 1;
break;
}
}
if(!alreadyThere)
{
oscillators.push_back(const_cast<SysOscillatorBase<T>*>(&src));
}
}
Please provide me some examples, in which I can see how it's a bad idea/unprofessional to use a const_cast.
Thank you for any efforts :)
Because you're thwarting the purpose of const, which is to keep you from modifying the argument. So if you cast away the constness of something, it's pointless and bloating your code, and it lets you break promises that you made to the user of the function that you won't modify the argument.
In addition, using const_cast can cause undefined behaviour. Consider this code:
SysOscillatorBase<int> src;
const SysOscillatorBase<int> src2;
...
aFieldTransformer.setOscillator(src);
aFieldTransformer.setOscillator(src2);
In the first call, all is well. You can cast away the constness of an object that is not really const and modify it fine. However, in the second call, in setOscillator you are casting away the constness of a truly const object. If you ever happen to modify that object in there anywhere, you are causing undefined behaviour by modifying an object that really is const. Since you can't tell whether an object marked const is really const where it was declared, you should just never use const_cast unless you are sure you'll never ever mutate the object ever. And if you won't, what's the point?
In your example code, you're storing a non-const pointer to an object that might be const, which indicates you intend to mutate the object (else why not just store a pointer to const?). That might cause undefined behaviour.
Also, doing it that way lets people pass a temporary to your function:
blah.setOscillator(SysOscillatorBase<int>()); // compiles
And then you're storing a pointer to a temporary which will be invalid when the function returns1. You don't have this problem if you take a non-const reference.
On the other hand, if I don't use const_cast, the code won't compile.
Then change your code, don't add a cast to make it work. The compiler is not compiling it for a reason. Now that you know the reasons, you can make your vector hold pointers to const instead of casting a square hole into a round one to fit your peg.
So, all around, it would be better to just have your method accept a non-const reference instead, and using const_cast is almost never a good idea.
1 Actually when the expression in which the function was called ends.
by using const, I'm protecting my reference from being changed
References can't be changed, once initialized they always refer to the same object. A reference being const means the object it refers to cannot be changed. But const_cast undoes that assertion and allows the object to be changed after all.
On the other hand, if I don't use const_cast, the code won't compile.
This isn't a justification for anything. C++ refuses to compile code that may allow a const object to be changed because that is the meaning of const. Such a program would be incorrect. const_cast is a means of compiling incorrect programs — that is the problem.
For example, in your program, it looks like you have an object
std::vector< SysOscillatorBase<T> * > oscillators
Consider this:
Oscillator o; // Create this object and obtain ownership
addOscillator( o ); // cannot modify o because argument is const
// ... other code ...
oscillators.back()->setFrequency( 3000 ); // woops, changed someone else's osc.
Passing an object by const reference means not only that the called function can't change it, but that the function can't pass it to someone else who can change it. const_cast violates that.
The strength of C++ is that it provides tools to guarantee things about ownership and value semantics. When you disable those tools to make the program compile, it enables bugs. No good programmer finds that acceptable.
As a solution to this particular problem, it looks likely that the vector (or whatever container you're using) should store the objects by value, not pointer. Then addOscillator can accept a const reference and yet the stored objects are modifiable. Furthermore, the container then owns the objects and ensures they are safely deleted, with no work on your part.
The use of const_cast for any reason other than adapting to (old) libraries where the interfaces have non-const pointers/references but the implementations don't modify the arguments is wrong and dangerous.
The reason that it is wrong is because when your interface takes a reference or pointer to a constant object you are promising not to change the object. Other code might depend on you not modifying the object. Consider for example, a type that holds an expensive to copy member, and that together with that it holds some other invariants.
Consider a vector<double> and a precomputed average value, the *average is updated whenever a new element is added through the class interface as it is cheap to update then, and if it is requested often there is no need to recompute it from the data every time. Because the vector is expensive to copy, but read access might be needed the type could offer a cheap accessor that returns a std::vector<double> const & for user code to check values already in the container. Now, if user code casts away the const-ness of the reference and updates the vector, the invariant that the class holds the average is broken and the behavior of your program becomes incorrect.
It is also dangerous because you have no guarantee that the object that you are passed is actually modifiable or not. Consider a simple function that takes a C null terminated string and converts that to uppercase, simple enough:
void upper_case( char * p ) {
while (*p) {
*p = ::to_upper(*p);
++p;
}
}
Now lets assume that you decide to change the interface to take a const char*, and the implementation to remove the const. User code that worked with the older version will also work with the new version, but some code that would be flagged as an error in the old version will not be detected at compile time now. Consider that someone decided to do something as stupid as upper_case( typeid(int).name() ). Now the problem is that the result of typeid is not just a constant reference to a modifiable object, but rather a reference to a constant object. The compiler is free to store the type_info object in a read-only segment and the loader to load it in a read-only page of memory. Attempting to change it will crash your program.
Note that in both cases, you cannot know from the context of the const_cast whether extra invariants are maintained (case 1) or even if the object is actually constant (case 2).
On the opposite end, the reason for const_cast to exist was adapting to old C code that did not support the const keyword. For some time functions like strlen would take a char*, even though it is known and documented that the function will not modify the object. In that case it is safe to use const_cast to adapt the type, not to change the const-ness. Note that C has support for const for a very long time already, and const_cast has lesser proper uses.
The const_cast would be bad because it allows you to break the contract specified by the method, i.e. "I shall not modify src". The caller expects the method to stick to that.
It's at least problematic. You have to distinguish two constnesses:
constness of the instantiated variable
This may result in physical constness, the data being placed in a read-only segment
constness of the reference parameter / pointer
This is a logical constness, only enforced by the compiler
You are allowed to cast away the const only if it's not physically const, and you can't determine that from the parameter.
In addition, it's a "smell" that some parts of your code are const-correct, and others aren't. This is sometimes unavoidable.
In your first example, you assign a const reference to what I assume is a non-const pointer. This would allow you to modify the original object, which requires at least a const cast. To illustrate:
SysOscillatorBase<int> a;
const SysOscillatorBase<int> b;
obj.setOscillator(a); // ok, a --> const a --> casting away the const
obj.setOscilaltor(b); // NOT OK: casting away the const-ness of a const instance
Same applies to your second example.
, while I can't really find the reason why const_cast is evil.
It is not, when used responsibily and when you know what you're doing. (Or do you seriously copy-paste code for all those methods that differ only by their const modifier?)
However, the problem with const_cast is that it can trigger undefined behavior if you use it on variable that originally was const. I.e. if you declare const variable, then const_cast it and attempt to modify it. And undefined behavior is not a good thing.
Your example contains precisely this situation: possibly const variable converted into non-const. To avoid the problem store either const SysOscillatorBase<T>*(const pointer) or SysOscillatorBase<T> (copy) in your object list, or pass reference instead of const reference.
You are violating a coding contract. Marking a value as const is saying you can use this value but never change it. const_cast breaks this promise and can create unexpected behaviour .
In the examples you give, it seems your code is not quite right. oscillatorSrc should probably be a const pointer, although if you really do need to change the value then you should not pass it in as a const at all.
Basicly const promises you and the compiler that you will not change the value. The only time you should use when you use a C library function (where const didn't exist), that is known not to change the value.
bool compareThatShouldntChangeValue(const int* a, const int* b){
int * c = const_cast<int*>(a);
*c = 7;
return a == b;
}
int main(){
if(compareThatShouldntChangeValue(1, 7)){
doSomething();
}
}
You probably need to define you container as containing const objects
template <typename T> struct Foo {
typedef std::vector<SysOscillator<T> const *> ossilator_vector;
}
Foo::ossilator_vector<int> oscillators;
// This will compile
SysOscillator<int> const * x = new SysOscillator<int>();
oscillators.push_back(x);
// This will not
SysOscillator<int> * x = new SysOscillator<int>();
oscillators.push_back(x);
That being said if you have no control over the typedef for the container maybe it
is ok to const_cast at the interface between your code and the library.

Passing by const copy

Is there any benefit (or conversely, cost) to passing a parameter by const value in the function signature?
So:
void foo( size_t nValue )
{
// ...
vs
void foo( const size_t nValue )
{
// ...
The only reason for doing this that I can think of would be to ensure the parameter wasn't modified as part of the function although since it has not been passed by reference there would be no wider impact outside the function.
The top-level const here affects only the definition of the function and only prevents you from modifying the value of nValue in the function.
The top-level const does not affect the function declaration. The following two declarations are exactly the same:
void foo(size_t nValue);
void foo(const size_t nValue);
Of course there is. You can't modify nValue inside the function.
As with const-ness in general, it's not a security measure, since you can cast it away, but a design matter.
You're explicitly telling other programmers that see your code -
"I will not modify nValue inside this function
and programmers that maintain or change your code
"If you want to modify nValue, you're probably doing something wrong. You shouldn't need to do this".
Using const you also ensure that you're not incorrectly trying to alter the value of the parameter inside the function, regardless if the parameter is modifiable or not.
if you define the input parameter const, you can just call const functions on that object.
anyway if you try to change that object accidentally, you will get a compiler error.
I've recently decided to do this. I like doing it as a sort of consistency with const & and const * parameters. const correctness makes life better, so why not go all in for it? If you know you're not going to change the value, why not make it const? Making it const communicates that intention clearly.

Should I return bool or const bool?

Which is better:
bool MyClass::someQuery() const;
const bool MyClass::someQuery() const;
I've been using 'const bool' since I'm sure I remember hearing it's "what the ints do" (for e.g. comparison operators) but I can't find evidence of that anywhere, mostly due to it being difficult to Google and Intellisense not helping out any ;) Can anyone confirm that?
To me returning const values (this isn't just about bools) makes more sense; it'll prevent temporaries being modified, which is almost always going to be a programmer mistake. I just want something to back that up so I can extol returning const values to my colleagues :)
This is the case when const adds no value but inflates the code and makes the reader think more. What's the point of this const? The caller can copy the value into some non-const variable and do whatever he wants with it anyway.
So you know it's right, you're just after the Voice of Authority?
Preventing accidental modification of temporaries is very valuable. In general, you should declare as many things as you possibly can const, it protects you from a variety of accidents and gives the optimiser useful hints.
D'you have a copy of Scott Meyers' "Effective C++" around? Point them at Item 3 (page 18 in the third edition) ;)
It gives the example of
class Rational {...};
const Rational operator* (const Rational& lhs, const Rational& rhs );
if( (a * b) = c ) // declaring operator *'s return value const causes error to be caught by compiler
Note that if((a*b) = c) won't compile for built-in types anyway, so it is very relevant here whether we're talking built-in types (your question asks for bool) or user-defined types.
For built-in types it makes no sense at all, so it shouldn't be used. And for user-defined types, I'm in jalf's camp: What if the caller wants to modify the returned object?
I'm not convinced that if((a*b) = c) is such a good argument for returning const user-defined types, since I can't remember the last time I've seen a compiler not warn about this.
To be a little more specific, only "objects" can be const. The C++ standard's definition of "object" includes everything an lvalue refers to ("has a name") and class-type temporaries. A boolean return value is an rvalue of a non-class type which is why a standards-compliant compiler will just ignore "const" in this case. As others said already, it's useless in this context.
When you returning a refernce to a member variable it makes sense to make it const. Here you are returning a copy, hence there is no need of const.
The const modifier is only used for return types that are returned by reference (either as reference const SomeObject& or via a pointer const SomeObject*), so the caller won't be able to modify the object via the reference/pointer. Primitive types are returned by value, which means that the caller receives a copy of the the object, not the object itself.
Therefore, const is not really appropriate for returned value types. Since the copy is outside of the control of the called function, the called function should not dictate to the caller that it cannot be changed.
This is an ancient post, but I think it's worth mentioning there is a potential corner case here since C++11. While, as stated by others, it will make no difference whether you use const bool or bool as return type in most cases, if you are using C++11 decltype and associates, e.g. result_of, you could declare a variable with the same type as the returning value of some function, and so the const would actually have an effect in this case.
It completely doesn't matter. Therefore, the consensus is to return just bool.
The reason that it doesn't matter is that you can't call non-const member functions anyway; bool is not a class or struct.
As bool is going to be copied, it's the same, to put const or not. Plus you'll may have some compil problems.
const return type
SUMMARY:
The value of a return type that is
declared const cannot be changed. This
is especially usefull when giving a
reference to a class’s internals, but
can also prevent rarer errors.
const bool func();
bool f = func();
0 errors, 0 warnings. What have you accomplished other than unnecessary code inflation?