How often do you declare your functions to be const? - c++

Do you find it helpful?

Every time You know that method won't change state of the object you should declare it to be constant.
It helps reading your code. And it helps when you try to change state of the object - compiler will stop you.

As often as possible. Functions that don't need to change data members should be declared as const. This makes code more understandable and may give hint to the compiler for optimization.

When you have a const object, the only methods that the compiler will let you call are those marked safe by the const keyword. In fact, only member methods make sense as const methods.
In C++, every method of an object receives an implicit this pointer to the object; A const method will simply receive a const this pointer.

Assuming you're talking about methods, as in:
struct Example {
void f() const;
};
Then if they should be callable on a const object, the method should be const.

Not often enough....
While all the answers are correct, if you are using a libary that is not const correct then it is difficult to use const all the places you should use it.
If you have an old API that takes a char * that for all logical purposes should be a const char *, then you either have to forget const in your code or do some ugly casting. In that case I forget const.

I use const at almost every opportunity, and like the fact it provides both documentation of intent and enforces compliance with that intent. Language features don't get much better than that, and yet const is curiously unloved. (The reality seems to be that the majority of self-proclaimed C++ coders can't explain the difference between int*, int*const, const int* and const int*const.)
While it could never have happened due to its 'C' origins, I often think C++ would be a better language if const had been the default and a liberal sprinkling of (say) 'var' or some similar keyword was necessary to allow post-construction modification of variables.

I used to declare functions as const but now I rarely if ever do it anymore.
The main problem was that if I wanted to change a function from const to non-const, it would mean that all other const functions calling that function would also need to be changed to non-const.
That happened more often than I thought due to optimization. For example I had a GetData() function which used to return a pointer to the data, but I later optimized to only set up the data if GetData() ends up being called (which changes the object's state, so it's no longer a const function).
Same thing for other functions that could do some calculation without changing the object's state, but at some point it made more sense caching the result since the function was called many times and was a bottleneck.
Also in practice, at least for my project, I saw very little benefit from declaring my functions as const.

Related

C++: Is there a point to add const to POD that are passed as arguments?

Imagine a function signature that accepts int or unsigned int or any POD.
Is there any benefits to const them if you are just reading from them>?
The only one I can think of, is so that you don't mess up and assign to it accidentally?
I am assuming that you are talking about the top-level qualifier as in void f( const type x ), rather than the const of the pointed/referred object. In that case, it is important to note that the language determines that the top level const-volatile qualifier in function arguments is removed from the signature of the function, that is, the following declare the same function:
void f( int );
void f( const int );
void f( volatile int );
void f( const volatile int );
From that point of view, in the declaration there is no point in adding cv-qualifiers. Now in the definition the cv-qualifiers are actually checked by the compiler, and in that case it will flag changes to the arguments as errors. I have seen some people suggesting you should and some suggesting you should not use const in the definitions to catch mistakes, but in most code I have seen, const was not used.
The only one I can think of, is so that you don't mess up and assign to it accidentally?
Yes, that's the point of const. Because of that, it's easier to analyse and reason about the purpose and correctness of the function.
Still, it's generally considered bad practice to make by-value (i.e. non-pointer/non-reference) arguments in public APIs const: if you later want to modify them in the implementation you'll need to choose between:
- edit the public header to remove const, which can trigger recompilation of client code (as is common with file modification timestamp driven make rules),
- if you don't remove the const from the implementation you may be forced to make an inefficient copy to yet another variable just to be able to modify the value....
- allow the declaration and definition to differ, which can confuse programmers flicking between the two (if they remember seeing it const somewhere but that isn't the implementation, they may make assumptions that prove to be wrong - the same danger doesn't exist for a non-const declaration that is actually const - at worst they check things unnecessarily carefully to find out the current state of the variable).
So, for functions internal to an implementation file, use const if you think it adds value (sometimes the verbosity is enough to make you not bother), but actively avoid it in public header files.
In Exceptional C++, Herb Sutter recommends:
"Avoid const pass-by-value parameters in function declarations. Still make the parameter const in the same function's definition if it won't be modified."
const correctness should be used more of an contract and not as an tool for optimization when used in function arguments.
It makes usage more intuitive and prevents honest programmers from making errors, other than than modern day compilers are competent enough to apply any optimizations required.
Let's clarify one thing: pointers qualify as POD, and it's common practice to declare them const.
As a matter of convention integer and floating-point parameters are never declared const, even if your function has no intention of changing them within its body. Any changes are only within the context of the function itself and never propagate back to the caller, so from the perspective of the public interface of the function declaring them const is redundant.
No need to decorate an int or uint param with const.
In this way, value was passed: a copy of this int or uint is generated and passed into your function. Within the function, any change won`t affect this outside int or unit.
Use const with pointer param.

Const correctness warnings c++

Does anyone know of any warnings that C++ compilers provide that help to enforce const correctness? For instance, it would be nice to have a warning produced by any C++ method that contains a non-const parameter that is never modified inside of the method. I see that there is a gnu compiler warning called -Wsuggest-attribute=const; however, when I use this flag I get an error saying that it is not recognized. Any ideas why?
I don't think such a warning exists, mostly because it would be useless. Just because a parameter is not modified inside the call, doesn't mean it should be made const just for the sake of it.
Think of virtual functions. Perhaps the designer of the base class, although not modifying the parameter in the base class, wants to leave it up to an extending class whether or not to modify that parameter.
Also, think of large applications, where modifying interfaces or API's or whatever costs a lot. You might not need to modify the parameter now, but intend to do so in the future. You're not going to make it const now, and force a full rebuild and probably risk errors in the future when you remove the const.
-Wsuggest-attribute=const
This analysis requires option
-fipa-pure-const
which is enabled by default at
-O
and higher
Careful, a const parameter like this one:
void myFunc(int const param);
does not belong to the interface. It belongs to the local scope of the function implementation. In fact, this function:
int inc(int const param) { return param+1; }
may be declared as
int inc(int param);
It is not a violation of the const correctness paradigm to claim the right to modify a variable but not actually do it.
If you are worried about const_cast you can either not use it in the first place or simply grep for it in your code base.
No, unfortunately there are no such warnings. You just get errors if you try to change const declared parameters. This is because missing const declarations do not change the correctness of the code from the compilers point of view. But const correctness is important for the compiler to discover potential optimizations and it improves the readability of the code. It is a matter of professionalism. Especially when using references const correctness is a must. I often refer to this.
The compiler itself takes const correctness very serious when operators (assignement, conversion, ...) come into play. A missing const here and the compiler refuses to use the operator because it makes a big difference if the given parameter may possibly be modified or not.
I'm not aware of such warnings and I think they would be rather hard to implement in a compiler - that is, they would slow it down. Maybe some static analysis tools have such features (but I'm not aware of those either).
As per Wsuggest-attribute=const, that is a different thing. It will suggest to use a gcc-specific "function attribute const", which is, basically, a mathematical function, receiving only values (no pointers), not reading or changing any static/global state and returning only a value (no pointers). For further description, look here: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes

const best practice in function declaration

Ive searched through the archived posts but I couldnt find anything similar.
Just a simple question: whats the best practice in declaring inspecting functions like:
int foo(int a) const { return a+1; }
Im referring to the const keyword, do you usually declare it at the end of an inspecting function? Im just asking because I usually do, even if 99% I wont declare any const class.. I just keep on tellin myself that it could save me some time if I ever should need to, but I was wondering if anybody else really cares about declaring const functions or if Im just paranoid about typesafe code
Assuming that you are talking about member functions (non member functions cannot be const ever), you should write const-correct code always, and that means that each and every function that does not modify the visible state of the object should be const.
Even if you don't ever create a constant object of the type, in many cases you will pass the object to a function through const references and in that case, only const member functions can be called on the object (Incidentally this means that you should pass the object by constant reference to any function that does not need to change the state of the received object)
The const appended at the end of the function declaration and definition indicates a contract between the caller of the function and the function that the function will not modify any members of that class.
So if your function provides guarantee for such an const-correctness contract you should extend it to users of your function.
Yes, of course you should if you want your program to support const correctness.
Const correctness has a way of propagating through your program once you begin declaring instances as const. As program complexity and your use of const increases, then you will either:
encounter many compiler errors when using const objects if you do not add them now
or your program will build without (or fewer) errors once you favor using const in the appropriate places.
or you may end up avoiding const for some time - which is (IMO) not a good road to go down if you want to improve your designs.
Over time, many of us have learned to use const in more than 1% of our code.

Making a char function parameter const?

Consider this function declaration:
int IndexOf(const char *, char);
where char * is a string and char the character to find within the string (returns -1 if the char is not found, otherwise its position). Does it make sense to make the char also const? I always try to use const on pointer parameters but when something is called by value, I normally leave the const away.
What are your thoughts?
Assuming you don't intend to adjust the value of either parameter:
I would have the function definition as:
int IndexOf( const char * const , const char )
{
//...
}
But keep the function declaration as:
int IndexOf( const char * , char );
In other words:
I'd reveal the bare minimum level of const in the header, but then use the maximum possible level of const in the implimentation.
Why?
Seperating the header and implimentation allows me to change the parameters that are const in the implimentation without ever touching the header (except those that are vitally const, which should require a header change).
It's makes the code more self-documenting.
It makes it harder to introduce bugs without the compiler catching them as errors.
It makes it harder for other programmers to introduce bugs when making future changes.
Making a pass-by-value paramter const or not has "no effect" in terms of affecting the caller of the function - which is why you should keep them out the header - but they can make your implimentation more robust and easier to maintain.
Obviously, if it's more useful to change the parameter rather than copying it into another local variable then don't make it const for the sake of doing so.
Contrary to my co-answerers, I'd make the char const. After all, you don't want to change the character you're looking for in mid-search, do you? And since doing so inadvertently has a good chance of messing up your algorithm, const helps to make your code robust and easy to maintain.
It doesn't make sense because the caller won't be affected if you modify the second parameter's value.
Further, if you need to modify this argument inside the function it may help you save a few bytes on the stack rather than having to declare a separate local variable.
The below code is a good example of modifying an argument instead of having a local variable:
void foo (int count) {
while (count--) {
do_something();
}
}
However, if your function is longer and you don't intend to modify its arguments, it may be rewarding in terms of maintenance to mark the corresponding arguments as const, but only in its definition, not in the declaration that resides in a header file. If you later decide that an argument shouldn't be const, you only have to change it in the definition.
For the example you gave the answers make sense, but in the more general case of passing by value there can be some instances where const might be helpful.
Generally this might be for non POD types where potentially even passing by value doesn't guarantee no visible side effects from changes. Furthermore if you absolutely know that your implementation won't be wanting to change it marking it const can help the compiler find bugs if/when someone accidentally changes the value later.
I tend to live by the rule "mark it const unless there's a reason for it to not be const"
I don't think it is necessary, as the char's value will be copied and any change to it won't be reflected outside of its scope.
It doesn't matter, so long as you are consistent.
As you can see, this question is a religious one. People come down on either side, and tend to fervently disagree with the opposing side.
Arguments can be made for or against either side. The arguments that are made can be contradicted.
For example, the arguments in the "make it const" camp tend to argue that it makes the code more self-documenting for maintenance programmers working on that function. This may well be true, and you might decide this is a good enough reason to mark your by-value parameters as const. The other side of this coin however is that you may decide one day that you do need to modify the variable in the function, which would require that you change the signature, or make a local copy. In addition, which marking is as const does add some documentation for the maintenance programmer, it also adds documentation for the client programmer -- but this documentation is misleading at best. It implies certain semantics to the caller that do not exist.
But whatever you do, you need to be consitant. Either make all your by-value parameters const, or none of them. Inconsitancy will destroy any of the documentary benefits you gain by taking either side.
If it's a 3 line function, the const doesn't help much.
But if you have to understand and maintain a 300 line function, it can be a very important clue that a local variable or parameter will not be changed before line 289, where it is used.
Pro const:
prevents the argument from being accidentally modified within the callee
Contra const:
adds clutter without providing useful information to the caller
implementation changes (ie removing the qualifier) will change the interface
The ideal solution would be to provide the const only in the declaration which is part of the function definition. However, the C standard does not allow this; it will work as expected in all reasonable implementations of the C language, though.
I'd say const would add absolutely nothing to your code.

Why is const-correctness specific to C++?

Disclaimer: I am aware that there are two questions about the usefulness of const-correctness, however, none discussed how const-correctness is necessary in C++ as opposed to other programming languages. Also, I am not satisfied with the answers provided to these questions.
I've used a few programming languages now, and one thing that bugs me in C++ is the notion of const-correctness. There is no such notion in Java, C#, Python, Ruby, Visual Basic, etc., this seems to be very specific to C++.
Before you refer me to the C++ FAQ Lite, I've read it, and it doesn't convince me. Perfectly valid, reliable programs are written in Python all the time, and there is no const keyword or equivalent. In Java and C#, objects can be declared final (or const), but there are no const member functions or const function parameters. If a function doesn't need to modify an object, it can take an interface that only provides read access to the object. That technique can equally be used in C++. On the two real-world C++ systems I've worked on, there was very little use of const anywhere, and everything worked fine. So I'm far from sold on the usefulness of letting const contaminate a codebase.
I am wondering what is it in C++ that makes const necessary, as opposed to other programming languages.
So far, I've seen only one case where const must be used:
#include <iostream>
struct Vector2 {
int X;
int Y;
};
void display(/* const */ Vector2& vect) {
std::cout << vect.X << " " << vect.Y << std::endl;
}
int main() {
display(Vector2());
}
Compiling this with const commented out is accepted by Visual Studio, but with warning C4239, non-standard extension used. So, if you want the syntactic brevity of passing in temporaries, avoiding copies, and staying standard-compliant, you have to pass by const reference, no way around it. Still, this is more like a quirk than a fundamental reason.
Otherwise, there really is no situation where const has to be used, except when interfacing with other code that uses const. Const seems to me little else than a self-righteous plague that spreads to everything it touches :
The reason that const works in C++ is
because you can cast it away. If you
couldn't cast it away, then your world
would suck. If you declare a method
that takes a const Bla, you could pass
it a non-const Bla. But if it's the
other way around you can't. If you
declare a method that takes a
non-const Bla, you can't pass it a
const Bla. So now you're stuck. So you
gradually need a const version of
everything that isn't const, and you
end up with a shadow world. In C++ you
get away with it, because as with
anything in C++ it is purely optional
whether you want this check or not.
You can just whack the constness away
if you don't like it.
Anders Hejlsberg (C# architect), CLR Design Choices
Const correctness provides two notable advantages to C++ that I can think of, one of which makes it rather unique.
It allows pervasive notions of mutable/immutable data without requiring a bunch of interfaces. Individual methods can be annotated as to whether or not they can be run on const objects, and the compiler enforces this. Yes, it can be a hassle sometimes, but if you use it consistently and don't use const_cast you have compiler-checked safety with regards to mutable vs. immutable data.
If an object or data item is const, the compiler is free to place it in read-only memory. This can particularly matter in embedded systems. C++ supports this; few other languages do. This also means that, in the general case, you cannot safely cast const away, although in practice you can do so in most environments.
C++ isn't the only language with const correctness or something like it. OCaml and Standard ML have a similar concept with different terminology — almost all data is immutable (const), and when you want something to be mutable you use a different type (a ref type) to accomplish that. So it's just unique to C++ within its neighboring languages.
Finally, coming the other direction: there have been times I have wanted const in Java. final sometimes doesn't go far enough as far as creating plainly immutable data (especially immutable views of mutable data), and don't want to create interfaces. Look at the Unmodifiable collection support in the Java API and the fact that it only checks at run time whether modification is allowed for an example of why const is useful (or at least the interface structure should be deepend to have List and MutableList) — there is no reason that attempting to mutate an immutable structure can't be a compile-type error.
I don't think anybody claims const-correctness is "necessary". But again, classes are not really necessary either, are they? The same goes for namespaces, exceptions,... you get the picture.
Const-correctness helps catch errors at compile time, and that's why it is useful.
const is a way for you to express something. It would be useful in any language, if you thought it was important to express it. They don't have the feature, because the language designers didn't find them useful. If the feature was there, it would be about as useful, I think.
I kind of think of it like throw specifications in Java. If you like them, you would probably like them in other languages. But the designers of the other languages didn't think it was that important.
Well, it will have taken me 6 years to really understand, but now I can finally answer my own question.
The reason C++ has "const-correctness" and that Java, C#, etc. don't, is that C++ only supports value types, and these other languages only support or at least default to reference types.
Let's see how C#, a language that defaults to reference types, deals with immutability when value types are involved. Let's say you have a mutable value type, and another type that has a readonly field of that type:
struct Vector {
public int X { get; private set; }
public int Y { get; private set; }
public void Add(int x, int y) {
X += x;
Y += y;
}
}
class Foo {
readonly Vector _v;
public void Add(int x, int y) => _v.Add(x, y);
public override string ToString() => $"{_v.X} {_v.Y}";
}
void Main()
{
var f = new Foo();
f.Add(3, 4);
Console.WriteLine(f);
}
What should this code do?
fail to compile
print "3, 4"
print "0, 0"
The answer is #3. C# tries to honor your "readonly" keyword by invoking the method Add on a throw-away copy of the object. That's weird, yes, but what other options does it have? If it invokes the method on the original Vector, the object will change, violating the "readonly"-ness of the field. If it fails to compile, then readonly value type members are pretty useless, because you can't invoke any methods on them, out of fear they might change the object.
If only we could label which methods are safe to call on readonly instances... Wait, that's exactly what const methods are in C++!
C# doesn't bother with const methods because we don't use value types that much in C#; we just avoid mutable value types (and declare them "evil", see 1, 2).
Also, reference types don't suffer from this problem, because when you mark a reference type variable as readonly, what's readonly is the reference, not the object itself. That's very easy for the compiler to enforce, it can mark any assignment as a compilation error except at initialization. If all you use is reference types and all your fields and variables are readonly, you get immutability everywhere at little syntactic cost. F# works entirely like this. Java avoids the issue by just not supporting user-defined value types.
C++ doesn't have the concept of "reference types", only "value types" (in C#-lingo); some of these value types can be pointers or references, but like value types in C#, none of them own their storage. If C++ treated "const" on its types the way C# treats "readonly" on value types, it would be very confusing as the example above demonstrates, nevermind the nasty interaction with copy constructors.
So C++ doesn't create a throw-away copy, because that would create endless pain. It doesn't forbid you to call any methods on members either, because, well, the language wouldn't be very useful then. But it still wants to have some notion of "readonly" or "const-ness".
C++ attempts to find a middle way by making you label which methods are safe to call on const members, and then it trusts you to have been faithful and accurate in your labeling and calls methods on the original objects directly. This is not perfect - it's verbose, and you're allowed to violate const-ness as much as you please - but it's arguably better than all the other options.
You're right, const-correctness isn't necessary. You can certainly write all your code without the const keyword and get things to work, just as you do in Java and Python.
But if you do that, you'll no longer get the compiler's help in checking for const violations. Errors that the compiler would have told you about at compile-time will now be found only at run-time, if at all, and therefore will take you longer to diagnose and fix.
Therefore, trying to subvert or avoid the const-correctness feature is just making things harder for yourself in the long run.
Programming is writing in a language that will be ultimately processed by the computer, but that is both a way of communicating with the computer and other programmers in the same project. When you use a language, you are restricted to the concepts that can be expressed in it, and const is just one more concept you can use to describe your problem, and your solution.
Constantness enables you to express clearly from the design board to the code one concept that other languages lack. As you come from a language that does not have it, you may seem puzzled by a concept you have never used --if you never used it before, how important can it be?
Language and thought are tightly coupled. You can only express your thoughts in the language you speak, but the language also changes the way you think. The fact that you did not have the const keyword in the languages you worked with implies that you have already found other solutions to the same problems, and those solutions are what seems natural to you.
In the question you argued that you can provide a non mutating interface that can be used by functions that do not need to change the contents of the objects. If you think about it for a second, this same sentence is telling you why const is a concept you want to work with.
Having to define a non-mutating interface and implement it in your class is a work around the fact that you cannot express that concept in your language.
Constantness allows you to express those concepts in a language that the compiler (and other programers) can understand. You are establishing a compromise on what you will do with the parameters you receive, the references you store, or defining limits on what the users of your class are allowed to do with the references you provide. Pretty much each non-trivial class can have a state represented by attributes, and in many cases there are invariants that must be kept. The language lets you define functions that offer access to some internal data while at the same time limits the access to a read-only view that guarantees no external code will break your invariants.
This is the concept I miss more when moving to other languages. Consider an scenario where you have a class C that has among others an attribute a of type A that must be visible to external code (users of your class must be able to query for some information on a). If the type of A has any mutating operation, then to keep user code from changing your internal state, you must create a copy of a and return it. The programmer of the class must be aware that a copy must be performed and must perform the (possibly expensive) copy. On the other hand, if you could express constantness in the language, you could just return a constant reference to the object (actually a reference to a constant view of the object) and just return the internal element. This will allow the user code to call any method of the object that is checked as non-mutating, thus preserving your class invariants.
The problem/advantage, all depends on the point of view, of constantness is that it is viral. When you offer a constant reference to an object, only those methods flagged as non-mutating can be called, and you must tell the compiler which of the methods have this property. When you declare a method constant, you are telling the compiler that user code that calls that method will keep the object state. When you define (implement) a method that has a constant signature, the compiler will remind you of your promise and actually require that you do not internally modify the data.
The language enables you to tell the compiler properties of your methods that you cannot express any other way, and at the same time, the compiler will tell you when you are not complying with your design and try to modify the data.
In this context, const_cast<> should never be used, as the results can take you into the realm of undefined behavior (both from a language point of view: the object could be in read-only memory, and from a program point of view: you might be breaking invariants in other classes). But that, of course, you already know if you read the C++FAQ lite.
As a side note, the final keyword in Java has really nothing to do with the const keyword in C++ when you are dealing with references (in C++ references or pointers). The final keyword modifies the local variable to which it refers, whether a basic type or a reference, but is not a modifier of the referred object. That is, you can call mutating methods through a final reference and thus provide changes in the state of the object referred. In C++, references are always constant (you can only bind them to an object/variable during construction) and the const keyword modifies how the user code can deal with the referred object. (In case of pointers, you can use the const keyword both for the datum and the pointer: X const * const declares a constant pointer to a constant X)
If you are writing programs for embedded devices with data in FLASH or ROM you can't live without const-correctness. It gives you the power to control the correct handling of data in different types of memory.
You want to use const in methods as well in order to take advantage of return value optimization. See Scott Meyers More Effective C++ item 20.
This talk and video from Herb Sutter explains the new connotations of const with regards to thread-safety.
Constness might not have been something you had to worry about too much before but with C++11 if you want to write thread-safe code you need to understand the significance of const and mutable
In C, Java and C# you can tell by looking at the call site if a passed object can be modified by a function:
in Java you know it definitely can be.
in C you know it only can be if there is a '&', or equivalent.
in c# you need to say 'ref' at the call site too.
In C++ in general you can't tell this, as a non-const reference call looks identical to pass-by-value. Having const references allows you to set up and enforce the C convention.
This can make a fairly major difference in readability of any code that calls functions. Which is probably enough to justify a language feature.
Anders Hejlsberg (C# architect): ... If you declare a method that takes a non-const Bla, you can't pass it a const Bla. So now you're stuck. So you gradually need a const version of everything that isn't const, and you end up with a shadow world.
So again: if you started to use "const" for some methods you usually forced to use this in most of your code. But the time spent for maintaining (typing, recompiling when some const is missing, etc.) of const-correctness in code seems greater than for fixing of possible (very rare) problems caused by not using of const-correctness at all. Thus lack of const-correctness support in modern languages (like Java, C#, Go, etc.) might result in slightly reduced development time for the same code quality.
An enhancement request ticket for implementing const correctness existed in the Java Community Process since 1999, but was closed in 2005 due to above mentioned "const pollution" and also compatibility reasons: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4211070
Although C# language has no const correctness construct but similar functionality possibly will appear soon in "Microsoft Code Contracts" (library + static analysis tools) for .NET Framework by using [Pure] and [Immutable] attributes: Pure functions in C#
Actually, it's not... not entirely, anyway.
In other languages, especially functional or hybrid languages, like Haskell, D, Rust, and Scala, you have the concept of mutability: variables can be mutable, or immutable, and are usually immutable by default.
This lets you (and your compiler/interpreter) reason better about functions: if you know that a function only takes immutable arguments, then you know that function isn't the one that's mutating your variable and causing a bug.
C and C++ do something similar using const, except that it's a much less firm guarantee: the immutability isn't enforced; a function further down the call stack could cast away the constness, and mutate your data, but that would be a deliberate violation of the API contract. So the intention or best practice is for it to work quite like immutability in other languages.
All that said, C++ 11 now has an actual mutable keyword, alongside the more limited const keyword.
The const keyword in C++ (as applied to parameters and type declarations) is an attempt to keep programmers from shooting off their big toe and taking out their whole leg in the process.
The basic idea is to label something as "cannot be modified". A const type can't be modified (by default). A const pointer can't point to a new location in memory. Simple, right?
Well, that's where const correctness comes in. Here are some of the possible combinations you can find yourself in when you use const:
A const variable
Implies that the data labeled by the variable name cannot be modified.
A pointer to a const variable
Implies that the pointer can be modified, but the data itself cannot.
A const pointer to a variable
Implies that the pointer cannot be modified (to point to a new memory location), but that the data to which the pointer points can be modified.
A const pointer to a const variable
Implies that neither the pointer nor the data to which it points can be modified.
Do you see how some things can be goofy there? That's why when you use const, it's important to be correct in which const you are labeling.
The point is that this is just a compile-time hack. The labeling just tells the compiler how to interpret instructions. If you cast away from const, you can do whatever you want. But you'll still have to call methods that have const requirements with types that are cast appropriately.
For example you have a funcion:
void const_print(const char* str)
{
cout << str << endl;
}
Another method
void print(char* str)
{
cout << str << endl;
}
In main:
int main(int argc, char **argv)
{
const_print("Hello");
print("Hello"); // syntax error
}
This because "hello" is a const char pointer, the (C-style) string is put in read only memory.
But it's useful overall when the programmer knows that the value will not be changed.So to get a compiler error instead of a segmentation fault.
Like in non-wanted assignments:
const int a;
int b;
if(a=b) {;} //for mistake
Since the left operand is a const int.