Why use prefixes on member variables in C++ classes - c++

A lot of C++ code uses syntactical conventions for marking up member variables. Common examples include
m_memberName for public members (where public members are used at all)
_memberName for private members or all members
Others try to enforce using this->member whenever a member variable is used.
In my experience, most larger code bases fail at applying such rules consistently.
In other languages, these conventions are far less widespread. I see it only occasionally in Java or C# code. I think I have never seen it in Ruby or Python code. Thus, there seems to be a trend with more modern languages to not use special markup for member variables.
Is this convention still useful today in C++ or is it just an anachronism. Especially as it is used so inconsistently across libraries. Haven't the other languages shown that one can do without member prefixes?

I'm all in favour of prefixes done well.
I think (System) Hungarian notation is responsible for most of the "bad rap" that prefixes get.
This notation is largely pointless in strongly typed languages e.g. in C++ "lpsz" to tell you that your string is a long pointer to a nul terminated string, when: segmented architecture is ancient history, C++ strings are by common convention pointers to nul-terminated char arrays, and it's not really all that difficult to know that "customerName" is a string!
However, I do use prefixes to specify the usage of a variable (essentially "Apps Hungarian", although I prefer to avoid the term Hungarian due to it having a bad and unfair association with System Hungarian), and this is a very handy timesaving and bug-reducing approach.
I use:
m for members
c for constants/readonlys
p for pointer (and pp for pointer to pointer)
v for volatile
s for static
i for indexes and iterators
e for events
Where I wish to make the type clear, I use standard suffixes (e.g. List, ComboBox, etc).
This makes the programmer aware of the usage of the variable whenever they see/use it. Arguably the most important case is "p" for pointer (because the usage changes from var. to var-> and you have to be much more careful with pointers - NULLs, pointer arithmetic, etc), but all the others are very handy.
For example, you can use the same variable name in multiple ways in a single function: (here a C++ example, but it applies equally to many languages)
MyClass::MyClass(int numItems)
{
mNumItems = numItems;
for (int iItem = 0; iItem < mNumItems; iItem++)
{
Item *pItem = new Item();
itemList[iItem] = pItem;
}
}
You can see here:
No confusion between member and parameter
No confusion between index/iterator and items
Use of a set of clearly related variables (item list, pointer, and index) that avoid the many pitfalls of generic (vague) names like "count", "index".
Prefixes reduce typing (shorter, and work better with auto-completion) than alternatives like "itemIndex" and "itemPtr"
Another great point of "iName" iterators is that I never index an array with the wrong index, and if I copy a loop inside another loop I don't have to refactor one of the loop index variables.
Compare this unrealistically simple example:
for (int i = 0; i < 100; i++)
for (int j = 0; j < 5; j++)
list[i].score += other[j].score;
(which is hard to read and often leads to use of "i" where "j" was intended)
with:
for (int iCompany = 0; iCompany < numCompanies; iCompany++)
for (int iUser = 0; iUser < numUsers; iUser++)
companyList[iCompany].score += userList[iUser].score;
(which is much more readable, and removes all confusion over indexing. With auto-complete in modern IDEs, this is also quick and easy to type)
The next benefit is that code snippets don't require any context to be understood. I can copy two lines of code into an email or a document, and anyone reading that snippet can tell the difference between all the members, constants, pointers, indexes, etc. I don't have to add "oh, and be careful because 'data' is a pointer to a pointer", because it's called 'ppData'.
And for the same reason, I don't have to move my eyes out of a line of code in order to understand it. I don't have to search through the code to find if 'data' is a local, parameter, member, or constant. I don't have to move my hand to the mouse so I can hover the pointer over 'data' and then wait for a tooltip (that sometimes never appears) to pop up. So programmers can read and understand the code significantly faster, because they don't waste time searching up and down or waiting.
(If you don't think you waste time searching up and down to work stuff out, find some code you wrote a year ago and haven't looked at
since. Open the file and jump about half way down without reading it.
See how far you can read from this point before you don't know if
something is a member, parameter or local. Now jump to another random
location... This is what we all do all day long when we are single
stepping through someone else's code or trying to understand how to
call their function)
The 'm' prefix also avoids the (IMHO) ugly and wordy "this->" notation, and the inconsistency that it guarantees (even if you are careful you'll usually end up with a mixture of 'this->data' and 'data' in the same class, because nothing enforces a consistent spelling of the name).
'this' notation is intended to resolve ambiguity - but why would anyone deliberately write code that can be ambiguous? Ambiguity will lead to a bug sooner or later. And in some languages 'this' can't be used for static members, so you have to introduce 'special cases' in your coding style. I prefer to have a single simple coding rule that applies everywhere - explicit, unambiguous and consistent.
The last major benefit is with Intellisense and auto-completion. Try using Intellisense on a Windows Form to find an event - you have to scroll through hundreds of mysterious base class methods that you will never need to call to find the events. But if every event had an "e" prefix, they would automatically be listed in a group under "e". Thus, prefixing works to group the members, consts, events, etc in the intellisense list, making it much quicker and easier to find the names you want. (Usually, a method might have around 20-50 values (locals, params, members, consts, events) that are accessible in its scope. But after typing the prefix (I want to use an index now, so I type 'i...'), I am presented with only 2-5 auto-complete options. The 'extra typing' people attribute to prefixes and meaningful names drastically reduces the search space and measurably accelerates development speed)
I'm a lazy programmer, and the above convention saves me a lot of work. I can code faster and I make far fewer mistakes because I know how every variable should be used.
Arguments against
So, what are the cons? Typical arguments against prefixes are:
"Prefix schemes are bad/evil". I agree that "m_lpsz" and its ilk are poorly thought out and wholly useless. That's why I'd advise using a well designed notation designed to support your requirements, rather than copying something that is inappropriate for your context. (Use the right tool for the job).
"If I change the usage of something I have to rename it". Yes, of course you do, that's what refactoring is all about, and why IDEs have refactoring tools to do this job quickly and painlessly. Even without prefixes, changing the usage of a variable almost certainly means its name ought to be changed.
"Prefixes just confuse me". As does every tool until you learn how to use it. Once your brain has become used to the naming patterns, it will filter the information out automatically and you won't really mind that the prefixes are there any more. But you have to use a scheme like this solidly for a week or two before you'll really become "fluent". And that's when a lot of people look at old code and start to wonder how they ever managed without a good prefix scheme.
"I can just look at the code to work this stuff out". Yes, but you don't need to waste time looking elsewhere in the code or remembering every little detail of it when the answer is right on the spot your eye is already focussed on.
(Some of) that information can be found by just waiting for a tooltip to pop up on my variable. Yes. Where supported, for some types of prefix, when your code compiles cleanly, after a wait, you can read through a description and find the information the prefix would have conveyed instantly. I feel that the prefix is a simpler, more reliable and more efficient approach.
"It's more typing". Really? One whole character more? Or is it - with IDE auto-completion tools, it will often reduce typing, because each prefix character narrows the search space significantly. Press "e" and the three events in your class pop up in intellisense. Press "c" and the five constants are listed.
"I can use this-> instead of m". Well, yes, you can. But that's just a much uglier and more verbose prefix! Only it carries a far greater risk (especially in teams) because to the compiler it is optional, and therefore its usage is frequently inconsistent. m on the other hand is brief, clear, explicit and not optional, so it's much harder to make mistakes using it.

I generally don't use a prefix for member variables.
I used to use a m prefix, until someone pointed out that "C++ already has a standard prefix for member access: this->.
So that's what I use now. That is, when there is ambiguity, I add the this-> prefix, but usually, no ambiguity exists, and I can just refer directly to the variable name.
To me, that's the best of both worlds. I have a prefix I can use when I need it, and I'm free to leave it out whenever possible.
Of course, the obvious counter to this is "yes, but then you can't see at a glance whether a variable is a class member or not".
To which I say "so what? If you need to know that, your class probably has too much state. Or the function is too big and complicated".
In practice, I've found that this works extremely well. As an added bonus it allows me to promote a local variable to a class member (or the other way around) easily, without having to rename it.
And best of all, it is consistent! I don't have to do anything special or remember any conventions to maintain consistency.
By the way, you shouldn't use leading underscores for your class members. You get uncomfortably close to names that are reserved by the implementation.
The standard reserves all names starting with double underscore or underscore followed by capital letter. It also reserves all names starting with a single underscore in the global namespace.
So a class member with a leading underscore followed by a lower-case letter is legal, but sooner or late you're going to do the same to an identifier starting with upper-case, or otherwise break one of the above rules.
So it's easier to just avoid leading underscores. Use a postfix underscore, or a m_ or just m prefix if you want to encode scope in the variable name.

You have to be careful with using a leading underscore. A leading underscore before a capital letter in a word is reserved.
For example:
_Foo
_L
are all reserved words while
_foo
_l
are not. There are other situations where leading underscores before lowercase letters are not allowed. In my specific case, I found the _L happened to be reserved by Visual C++ 2005 and the clash created some unexpected results.
I am on the fence about how useful it is to mark up local variables.
Here is a link about which identifiers are reserved:
What are the rules about using an underscore in a C++ identifier?

I prefer postfix underscores, like such:
class Foo
{
private:
int bar_;
public:
int bar() { return bar_; }
};

Lately I have been tending to prefer m_ prefix instead of having no prefix at all, the reasons isn't so much that its important to flag member variables, but that it avoids ambiguity, say you have code like:
void set_foo(int foo) { foo = foo; }
That of cause doesn't work, only one foo allowed. So your options are:
this->foo = foo;
I don't like it, as it causes parameter shadowing, you no longer can use g++ -Wshadow warnings, its also longer to type then m_. You also still run into naming conflicts between variables and functions when you have a int foo; and a int foo();.
foo = foo_; or foo = arg_foo;
Been using that for a while, but it makes the argument lists ugly, documentation shouldn't have do deal with name disambiguity in the implementation. Naming conflicts between variables and functions also exist here.
m_foo = foo;
API Documentation stays clean, you don't get ambiguity between member functions and variables and its shorter to type then this->. Only disadvantage is that it makes POD structures ugly, but as POD structures don't suffer from the name ambiguity in the first place, one doesn't need to use it with them. Having a unique prefix also makes a few search&replace operations easier.
foo_ = foo;
Most of the advantages of m_ apply, but I reject it for aesthetic reasons, a trailing or leading underscore just makes the variable look incomplete and unbalanced. m_ just looks better. Using m_ is also more extendable, as you can use g_ for globals and s_ for statics.
PS: The reason why you don't see m_ in Python or Ruby is because both languages enforce the their own prefix, Ruby uses # for member variables and Python requires self..

When reading through a member function, knowing who "owns" each variable is absolutely essential to understanding the meaning of the variable. In a function like this:
void Foo::bar( int apples )
{
int bananas = apples + grapes;
melons = grapes * bananas;
spuds += melons;
}
...it's easy enough to see where apples and bananas are coming from, but what about grapes, melons, and spuds? Should we look in the global namespace? In the class declaration? Is the variable a member of this object or a member of this object's class? Without knowing the answer to these questions, you can't understand the code. And in a longer function, even the declarations of local variables like apples and bananas can get lost in the shuffle.
Prepending a consistent label for globals, member variables, and static member variables (perhaps g_, m_, and s_ respectively) instantly clarifies the situation.
void Foo::bar( int apples )
{
int bananas = apples + g_grapes;
m_melons = g_grapes * bananas;
s_spuds += m_melons;
}
These may take some getting used to at first—but then, what in programming doesn't? There was a day when even { and } looked weird to you. And once you get used to them, they help you understand the code much more quickly.
(Using "this->" in place of m_ makes sense, but is even more long-winded and visually disruptive. I don't see it as a good alternative for marking up all uses of member variables.)
A possible objection to the above argument would be to extend the argument to types. It might also be true that knowing the type of a variable "is absolutely essential to understanding the meaning of the variable." If that is so, why not add a prefix to each variable name that identifies its type? With that logic, you end up with Hungarian notation. But many people find Hungarian notation laborious, ugly, and unhelpful.
void Foo::bar( int iApples )
{
int iBananas = iApples + g_fGrapes;
m_fMelons = g_fGrapes * iBananas;
s_dSpuds += m_fMelons;
}
Hungarian does tell us something new about the code. We now understand that there are several implicit casts in the Foo::bar() function. The problem with the code now is that the value of the information added by Hungarian prefixes is small relative to the visual cost. The C++ type system includes many features to help types either work well together or to raise a compiler warning or error. The compiler helps us deal with types—we don't need notation to do so. We can infer easily enough that the variables in Foo::bar() are probably numeric, and if that's all we know, that's good enough for gaining a general understanding of the function. Therefore the value of knowing the precise type of each variable is relatively low. Yet the ugliness of a variable like "s_dSpuds" (or even just "dSpuds") is great. So, a cost-benefit analysis rejects Hungarian notation, whereas the benefit of g_, s_, and m_ overwhelms the cost in the eyes of many programmers.

I can't say how widespred it is, but speaking personally, I always (and have always) prefixed my member variables with 'm'. E.g.:
class Person {
....
private:
std::string mName;
};
It's the only form of prefixing I do use (I'm very anti Hungarian notation) but it has stood me in good stead over the years. As an aside, I generally detest the use of underscores in names (or anywhere else for that matter), but do make an exception for preprocessor macro names, as they are usually all uppercase.

The main reason for a member prefix is to distinguish between a member function and a member variable with the same name. This is useful if you use getters with the name of the thing.
Consider:
class person
{
public:
person(const std::string& full_name)
: full_name_(full_name)
{}
const std::string& full_name() const { return full_name_; }
private:
std::string full_name_;
};
The member variable could not be named full_name in this case. You need to rename the member function to get_full_name() or decorate the member variable somehow.

I don't think one syntax has real value over another. It all boils down, like you mentionned, to uniformity across the source files.
The only point where I find such rules interesting is when I need 2 things named identicaly, for example :
void myFunc(int index){
this->index = index;
}
void myFunc(int index){
m_index = index;
}
I use it to differentiate the two. Also when I wrap calls, like from windows Dll, RecvPacket(...) from the Dll might be wrapped in RecvPacket(...) in my code. In these particular occasions using a prefix like "_" might make the two look alike, easy to identify which is which, but different for the compiler

Some responses focus on refactoring, rather than naming conventions, as the way to improve readability. I don't feel that one can replace the other.
I've known programmers who are uncomfortable with using local declarations; they prefer to place all the declarations at the top of a block (as in C), so they know where to find them. I've found that, where scoping allows for it, declaring variables where they're first used decreases the time that I spend glancing backwards to find the declarations. (This is true for me even for small functions.) That makes it easier for me to understand the code I'm looking at.
I hope it's clear enough how this relates to member naming conventions: When members are uniformly prefixed, I never have to look back at all; I know the declaration won't even be found in the source file.
I'm sure that I didn't start out preferring these styles. Yet over time, working in environments where they were used consistently, I optimized my thinking to take advantage of them. I think it's possible that many folks who currently feel uncomfortable with them would also come to prefer them, given consistent usage.

Those conventions are just that. Most shops use code conventions to ease code readability so anyone can easily look at a piece of code and quickly decipher between things such as public and private members.

Others try to enforce using
this->member whenever a member
variable is used
That is usually because there is no prefix. The compiler needs enough information to resolve the variable in question, be it a unique name because of the prefix, or via the this keyword.
So, yes, I think prefixes are still useful. I, for one, would prefer to type '_' to access a member rather than 'this->'.

Other languages will use coding conventions, they just tend to be different. C# for example has probably two different styles that people tend to use, either one of the C++ methods (_variable, mVariable or other prefix such as Hungarian notation), or what I refer to as the StyleCop method.
private int privateMember;
public int PublicMember;
public int Function(int parameter)
{
// StyleCop enforces using this. for class members.
this.privateMember = parameter;
}
In the end, it becomes what people know, and what looks best. I personally think code is more readable without Hungarian notation, but it can become easier to find a variable with intellisense for example if the Hungarian notation is attached.
In my example above, you don't need an m prefix for member variables because prefixing your usage with this. indicates the same thing in a compiler-enforced method.
This doesn't necessarily mean the other methods are bad, people stick to what works.

When you have a big method or code blocks, it's convenient to know immediately if you use a local variable or a member. it's to avoid errors and for better clearness !

IMO, this is personal. I'm not putting any prefixes at all. Anyway, if code is meaned to be public, I think it should better has some prefixes, so it can be more readable.
Often large companies are using it's own so called 'developer rules'.
Btw, the funniest yet smartest i saw was DRY KISS (Dont Repeat Yourself. Keep It Simple, Stupid). :-)

As others have already said, the importance is to be colloquial (adapt naming styles and conventions to the code base in which you're writing) and to be consistent.
For years I have worked on a large code base that uses both the "this->" convention as well as using a postfix underscore notation for member variables. Throughout the years I've also worked on smaller projects, some of which did not have any sort of convention for naming member variables, and other which had differing conventions for naming member variables. Of those smaller projects, I've consistently found those which lacked any convention to be the most difficult to jump into quickly and understand.
I'm very anal-retentive about naming. I will agonize over the name to be ascribed to a class or variable to the point that, if I cannot come up with something that I feel is "good", I will choose to name it something nonsensical and provide a comment describing what it really is. That way, at least the name means exactly what I intend it to mean--nothing more and nothing less. And often, after using it for a little while, I discover what the name should really be and can go back and modify or refactor appropriately.
One last point on the topic of an IDE doing the work--that's all nice and good, but IDEs are often not available in environments where I have perform the most urgent work. Sometimes the only thing available at that point is a copy of 'vi'. Also, I've seen many cases where IDE code completion has propagated stupidity such as incorrect spelling in names. Thus, I prefer to not have to rely on an IDE crutch.

The original idea for prefixes on C++ member variables was to store additional type information that the compiler didn't know about. So for example, you could have a string that's a fixed length of chars, and another that's variable and terminated by a '\0'. To the compiler they're both char *, but if you try to copy from one to the other you get in huge trouble. So, off the top of my head,
char *aszFred = "Hi I'm a null-terminated string";
char *arrWilma = {'O', 'o', 'p', 's'};
where "asz" means this variable is "ascii string (zero-terminated) and "arr" means this variable is a character array.
Then the magic happens. The compiler will be perfectly happy with this statement:
strcpy(arrWilma, aszFred);
But you, as a human, can look at it and say "hey, those variables aren't really the same type, I can't do that".
Unfortunately a lot places use standards such as "m_" for member variables, "i" for integers no matter how used, "cp" for char pointers. In other words they're duplicating what the compiler knows, and making the code hard to read at the same time. I believe this pernicious practice should be outlawed by statute and subject to harsh penalties.
Finally, there's two points I should mention:
Judicious use of C++ features allows the compiler to know the information you had to encode in raw C-style variables. You can make classes that will only allow valid operations. This should be done as much as practical.
If your code blocks are so long that you forget what type a variable is before you use it, they are way too long. Don't use names, re-organize.

Our project has always used "its" as a prefix for member data, and "the" as a prefix for parameters, with no prefix for locals. It's a little cutesy, but it was adopted by the early developers of our system because they saw it used as a convention by some commercial source libraries we were using at the time (either XVT or RogueWave - maybe both). So you'd get something like this:
void
MyClass::SetName(const RWCString &theName)
{
itsName = theName;
}
The big reason I see for scoping prefixes (and no others - I hate Hungarian notation) is that it prevents you from getting into trouble by writing code where you think you're referring to one variable, but you're really referring to another variable with the same name defined in the local scope. It also avoids the problem of coming up with a variable names to represent that same concept, but with different scopes, like the example above. In that case, you would have to come up with some prefix or different name for the parameter "theName" anyway - why not make a consistent rule that applies everywhere.
Just using this-> isn't really good enough - we're not as interested in reducing ambiguity as we are in reducing coding errors, and masking names with locally scoped identifiers can be a pain. Granted, some compilers may have the option to raise warnings for cases where you've masked the name in a larger scope, but those warnings may become a nuisance if you're working with a large set of third party libraries that happen to have chosen names for unused variables that occasionally collide with your own.
As for the its/the itself - I honestly find it easier to type than underscores (as a touch typist, I avoid underscores whenever possible - too much stretching off the home rows), and I find it more readable than a mysterious underscore.

I use it because VC++'s Intellisense can't tell when to show private members when accessing out of the class. The only indication is a little "lock" symbol on the field icon in the Intellisense list. It just makes it easier to identify private members(fields) easier. Also a habit from C# to be honest.
class Person {
std::string m_Name;
public:
std::string Name() { return m_Name; }
void SetName(std::string name) { m_Name = name; }
};
int main() {
Person *p = new Person();
p->Name(); // valid
p->m_Name; // invalid, compiler throws error. but intellisense doesn't know this..
return 1;
}

I think that, if you need prefixes to distinguish class members from member function parameters and local variables, either the function is too big or the variables are badly named. If it doesn't fit on the screen so you can easily see what is what, refactor.
Given that they often are declared far from where they are used, I find that naming conventions for global constants (and global variables, although IMO there's rarely ever a need to use those) make sense. But otherwise, I don't see much need.
That said, I used to put an underscore at the end of all private class members. Since all my data is private, this implies members have a trailing underscore. I usually don't do this anymore in new code bases, but since, as a programmer, you mostly work with old code, I still do this a lot. I'm not sure whether my tolerance for this habit comes from the fact that I used to do this always and am still doing it regularly or whether it really makes more sense than the marking of member variables.

In python leading double underscores are used to emulate private members. For more details see this answer

I use m_ for member variables just to take advantage of Intellisense and related IDE-functionality. When I'm coding the implementation of a class I can type m_ and see the combobox with all m_ members grouped together.
But I could live without m_ 's without problem, of course. It's just my style of work.

It is useful to differentiate between member variables and local variables due to memory management. Broadly speaking, heap-allocated member variables should be destroyed in the destructor, while heap-allocated local variables should be destroyed within that scope. Applying a naming convention to member variables facilitates correct memory management.

Code Complete recommends m_varname for member variables.
While I've never thought the m_ notation useful, I would give McConnell's opinion weight in building a standard.

I almost never use prefixes in front of my variable names. If you're using a decent enough IDE you should be able to refactor and find references easily. I use very clear names and am not afraid of having long variable names. I've never had trouble with scope either with this philosophy.
The only time I use a prefix would be on the signature line. I'll prefix parameters to a method with _ so I can program defensively around them.

You should never need such a prefix. If such a prefix offers you any advantage, your coding style in general needs fixing, and it's not the prefix that's keeping your code from being clear. Typical bad variable names include "other" or "2". You do not fix that with requiring it to be mOther, you fix it by getting the developer to think about what that variable is doing there in the context of that function. Perhaps he meant remoteSide, or newValue, or secondTestListener or something in that scope.
It's an effective anachronism that's still propagated too far. Stop prefixing your variables and give them proper names whose clarity reflects how long they're used. Up to 5 lines you could call it "i" without confusion; beyond 50 lines you need a pretty long name.

I like variable names to give only a meaning to the values they contain, and leave how they are declared/implemented out of the name. I want to know what the value means, period. Maybe I've done more than an average amount of refactoring, but I find that embedding how something is implemented in the name makes refactoring more tedious than it needs to be. Prefixes indicating where or how object members are declared are implementation specific.
color = Red;
Most of the time, I don't care if Red is an enum, a struct, or whatever, and if the function is so large that I can't remember if color was declared locally or is a member, it's probably time to break the function into smaller logical units.
If your cyclomatic complexity is so great that you can't keep track of what is going on in the code without implementation-specific clues embedded in the names of things, most likely you need to reduce the complexity of your function/method.
Mostly, I only use 'this' in constructors and initializers.

According to JOINT STRIKE FIGHTER AIR VEHICLE C++ CODING STANDARDS (december 2005):
AV Rule 67
Public and protected data should only be used in
structs—not classes. Rationale: A class is able to maintain its
invariant by controlling access to its data. However, a class cannot
control access to its members if those members non-private. Hence all
data in a class should be private.
Thus, the "m" prefix becomes unuseful as all data should be private.
But it is a good habit to use the p prefix before a pointer as it is a dangerous variable.

Many of those conventions are from a time without sophisticated editors. I would recommend using a proper IDE that allows you to color every kind of variable. Color is by far easier to spot than any prefix.
If you need to get even more detail on a variable any modern IDE should be able to show it to you by moving the caret or cursor over it. And if you use a variable in a wrong way (for instance a pointer with the . operator) you will get an error, anyway.

Personally I use a relatively "simple" system to denote what variables are
I have the different "flags" that I combine then an underscore, then the memory type, then finally the name.
I like this because you can narrow down the amount of variables in an IDE's completion as much as possible as quickly as possible.
The stuff I use is:
m for member function
s for static
c for const/constexpr
then an underscore _
then the variable memory type
p for unowned pointer
v for list
r for reference
nothing for owned value
for example if I had a member variable which is a list of ints I would put
m_vName
and for a static const pointer to a pointer of lists of ints I would put
sc_ppvName
This lets me quickly tell what The variable is used for and how to access it. aswell as how to get/drop values

Related

C++ alias for a global variable/instance object of a class

I have this, a header file with class declaration and one global object instance:
struct ClassName
{
};
extern ClassName ClassObject;
But in CPP codes I'd like to access it via shorter name, for example CO instead of ClassObject
Ideally I'd like to do something like typedef ClassObject CO; but it's not supported
I don't want to use #define CO ClassObject because it's dangerous.
I don't want to use
extern ClassName &CO;
ClassName &CO=ClassObject;
Because that would decrease performance, accessing CO would have to lookup the address value first, while ClassObject wouldn't have to. So using ClassObject would be faster than CO, but I need same performance.
Tried with a union
union
{
ClassName ClassObject;
ClassName CO;
};
but it requires union to be static, so can't declare in header and share across other CPP files.
So there's no solution for this?
This is an unfortunately common design malady, wherein a programmer arbitrarily defines the problem so narrowly that they define away all possible solutions to that problem.
Macros are deemed "dangerous", despite there not actually being anything especially dangerous about this particular macro; it's just a name that turns into a different name (being only two letters is conceptually dangerous, but no more so than using a 2-letter identifier). So it is disregarded, even though it is workable solution (aside from the lack of namespace scoping, but you almost certainly aren't interested in that since you want the name to be as short as possible).
References are deemed to "decrease performance", despite a lack of evidence for references being slow in this particular case nor of the performance of your application being materially affected by an indirect access to a globally accessible object. So it is disregarded, even though this is a perfectly valid use of references in C++ and is directly analogous to type aliases.
If you start from the presupposition that all of the good solutions are bad, then you're obviously not going to be left with any good solutions. And that's where you find yourself.
But really, the best solution is to avoid creating tiny aliases for variables like this to begin with. It's one thing to create aliases for complex template classes like std::vector<int, MyAllocator<int>> and so forth, where there is a huge amount of cruft and verbiage spent on something that's much simpler than it appears. It's quite another to abbreviate an object name, particularly if the abbreviation is as short as 2 letters.
If the 2 letter name is an adequately descriptive name within this context, then that's what it should always be called. If the long name is long because it needs to be that long in order to be adequately descriptive, then odds are good that this descriptiveness will be important everywhere it gets used. And regardless of how you implement this alias, having two names for the same object in the same scope will get confusing to someone who has to read this code and figure out what it's doing. And that "someone" may well be your future self.
So just... don't do this.
only this "extern ClassName &CO;" would be in the header. So when compiling CPP files, they wouldn't know to what CO actually points.
If that really, really, really bothers you, C++17 offers inline variables, which would allow you to put inline ClassName &CO = ClassObject; in your headers.

Why does std::filesystem provide so many non-member functions?

Consider for example
file_size. To get the size of a file we will be using
std::filesystem::path p = std::filesystem::current_path();
// ... usual "does this exist && is this a file" boilerplate
auto n = std::filesystem::file_size(p);
Nothing wrong with that, if it were plain ol' C, but having been taught that C++ is an OO language [I do know it's multi-paradigm, apologies to our language lawyers :-)] that just feels so ... imperative (shudder) to me, where I have come to expect the object-ish
auto n = p.file_size();
instead. The same holds for other functions, such as resize_file, remove_file and probably more.
Do you know of any rationale why Boost and consequently std::filesystem chose this imperative style instead of the object-ish one? What is the benefit? Boost mentions the rule (at the very bottom), but no rationale for it.
I was thinking about inherent issues such as ps state after remove_file(p), or error flags (overloads with additional argument), but neither approach solves these less elegant than the other.
You can observe a similar pattern with iterators, where nowadays we can (are supposed to?) do begin(it) instead of it.begin(), but here I think the rationale was to be more in line with the non-modifying next(it) and such.
There are a couple of good answers already posted, but they do not get to the heart of the matter: all other things being equal, if you can implement something as a free, non-friend function, you always should.
Why?
Because, free, non-friend functions, do not have privileged access to state. Testing classes is much harder than testing functions because you have to convince yourself that the class' invariants are maintained no matter which members functions are called, or even combinations of member functions. The more member/friend functions you have, the more work you have to do.
Free functions can be reasoned about and tested standalone. Because they don't have privileged access to class state, they cannot possibly violate any class invariants.
I don't know the details of what invariants and what privileged access path allows, but obviously they were able to implement a lot of functionality as free functions, and they make the right choice and did so.
Scott Meyers brilliant article on this topic, giving the "algorithm" for whether to make a function a member or not.
Here's Herb Sutter bemoaning the massive interface of std::string. Why? Because, much of string's interface could have been implemented as free functions. It may be a bit more unwieldy to use on occasion, but it's easier to test, reason about, improves encapsulation and modularity, opens opportunities up for code reuse that were not there before, etc.
The Filesystem library has a very clear separation between the filesystem::path type, which represents an abstract path name (that doesn't even have be the name of a file that exists) and operations that access the actual physical filesystem, i.e. read+write data on disks.
You even pointed to the explanation of that:
The design rule is that purely lexical operations are supplied as class path member functions, while operations performed by the operating system are provided as free functions.
This is the reason.
It's theoretically possible to use a filesystem::path on a system with no disks. The path class just holds a string of characters and allows manipulating that string, converting between character sets and using some rules that define the structure of filenames and pathnames on the host OS. For example it knows that directory names are separated by / on POSIX systems and by \ on Windows. Manipulating the string held in a path is a "lexical operation", because it just performs string manipulation.
The non-member functions that are known as "filesystem operations" are entirely different. They don't just work with an abstract path object that is just a string of characters, they perform the actual I/O operations that access the filesystem (stat system calls, open, readdir etc.). These operations take a path argument that names the files or directories to operate on, and then they access the real files or directories. They don't just manipulate strings in memory.
Those operations depend on the API provided by the OS for accessing files, and they depend on hardware that might fail in completely different ways to in-memory string manipulations. Disks might be full, or might get unplugged before an operation completes, or might have hardware faults.
Looked at like that, of course file_size isn't a member of path, because it's nothing to do with the path itself. The path is just a representation of a filename, not of an actual file. The function file_size looks for a physical file with the given name and tries to read its size. That's not a property of the file name, it's a property of a persistent file on the filesystem. Something that exists entirely separately from the string of characters in memory that holds the name of a file.
Put another way, I can have a path object that contains complete nonsense, like filesystem::path p("hgkugkkgkuegakugnkunfkw") and that's fine. I can append to that path, or ask if it has a root directory etc. But I can't read the size of such a file if it doesn't exist. I can have a path to files that do exist, but I don't have permission to access, like filesystem::path p("/root/secret_admin_files.txt"); and that's also fine, because it's just a string of characters. I'd only get a "permission denied" error when I tried to access something in that location using the filesystem operation functions.
Because path member functions never touch the filesystem they can never fail due to permissions, or non-existent files. That's a useful guarantee.
You can observe a similar pattern with iterators, where nowadays we can (are supposed to?) do begin(it) instead of it.begin(), but here I think the rationale was to be more in line with the non-modifying next(it) and such.
No, it was because it works equally well with arrays (which can't have member functions) and class types. If you know the range-like thing you are dealing with is a container not an array then you can use x.begin() but if you're writing generic code and don't know whether it's a container or an array then std::begin(x) works in both cases.
The reasons for both these things (the filesystem design and the non-member range access functions) are not some anti-OO preference, they're for far more sensible, practical reasons. It would have been poor design to have based either of them because it feels better to some people who like OO, or feels better to people who don't like OO.
Also, there are things you can't do when everything's a member function:
struct ConvertibleToPath {
operator const std::filesystem::path& () const;
// ...
};
ConvertibleToPath c;
auto n = std::filesystem::file_size(c); // works fine
But if file_size was a member of path:
c.file_size(); // wouldn't work
static_cast<const std::filesystem::path&>(c).file_size(); // yay, feels object-ish!
Several reasons (somewhat speculative though, I don't follow the standardization process very closely):
Because it's based on boost::filesystem, which is designed that way. Now, you could ask "Why is boost::filesystem designed that way?", which would be a fair question, but given that it was, and that it's seen a lot of mileage the way it is, it was accepted into the standard with very few changes. So were some other Boost constructs (although sometimes there are some changes, under the hood mostly).
A common principle when designing classes is "if a function doesn't need access to a class' protected/private members, and can instead use existing members - you don't make it a member as well." While not everyone ascribes to that - it seems the designers of boost::filesystem do.
See a discussion of (and an argument for) this in the context of std::string(), a "monolith" class with a zillion methods, by C++ luminary Hebert Sutter, in Guru of the Week #84.
It was expected that in C++17 we might already have Uniform Call Syntax (see Bjarne's Stroustrup highly-readable proposal). If that had been accepted into the standard, calling
p.file_size();
would have been equivalent to calling
file_size(p);
so you could have chosen whatever you like. Basically.
Just in addition to what others already stated.
One of the reasons why people are unhappy with "nonmember" approach is the need to type std::filesystem:: in the front of the API or to use using directives.
But actually you don't have to, and simply skipping namespace for API call like this:
#include <iostream>
#include <filesystem>
int main()
{
auto p = std::filesystem::path{"/bin/cat"};
//notice file_size below has no namespace qualifiers
std::cout << "Binary size for your /bin/cat is " << file_size(p);
}
works perfectly fine because of function names are also looked up in the namespaces of their arguments due to ADL.
(live sample https://wandbox.org/permlink/JrFz8FJG3OdgRwg9)

Is it okay to use the this pointer? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Is there any reason to use this->
When should this-> be used?
When should I make explicit use of the this pointer?
When working with pointers to classes, I like to add a this-> in front of variables in a class to make it clearer that the variable I'm talking about is in the current class, as opposed to temporary variables, etc. So my lines would be something like
if(this->thing > other->thing)
this->doFoo();
Instead of
if(thing > other->thing)
doFoo();
Is it okay to add the superfluous this, or would that degrade code readability?
Consistency consistency consistency.
I conisder the this-> prefix a valid coding style if you use it throughout your entire project everywhere a member is accessed.
I prefer using a signifying prefix for members, e.g. m_. I feel it is less cutter and less tag soup than the explicit this->:
(alpha-this->gamma > this->alpha-gamma)
vs.
(alpha-m_gamma > m_alpha-gamma)
(The dotNetties have labeled m_ outdated - I use it on small C# projects out of spite. but anyway, any other distinct prefix would do, too.)
I've seen it used often to help intellisense get in gear, or to specifically filter members - which is ok, though leaving it in for that reason is questionable, especially if not used consistently.
That depends on your coding style, however many people would use
_myVariable
m_myVariable
myVariable_
To differentiate member variables from the other.
But the most important thing is to just be consistent
This is a style question, so answers will be subjective. Similarly, a lot of people I've worked with like to prefix member variables with m_ to make it clear that it's a member. (m_foo would be like your this->foo.) Then I'm sure there are people who feel this is a crime against the universe. YMMV. Use what works for you and anyone you might be working with.
One advantage (or disadvantage, depending on who you ask) to this-> is that you can have a variable with the same name that can be both a member and something locally scoped like a parameter or local variable, eg.:
foo bar;
void f(foo bar)
{
this->bar = bar;
}
As already noted this is, mostly, a matter of style.
Personally I do not use it for the data-members (I use the m prefix alternative), however I do use it for functions:
for consistency with templated code, where this might be necessary to defer lookup
for clarity, in order to distinguish at a glance whether it's a method of the class (possibly a base class) or a free-standing function
I think that, since you definitely don't want to trudge through levels of base class when reading up some code, the this-> clarification makes it much easier for the reader. And it's only 6 more characters to type.
I like this pattern too, but I like it more in managed code where it's "this." - the arrow operator does feel a bit noisier, but still it makes it very clear when you're referring to instance-level stuff.
of course you can do it, besides, the compiler would add it for you.
Normally you use this notation, when your method arguments and the member variables have the same name. (to differentiate the method argument with the member variable)
Say for e.g,
void CMYClass::fun1(int sameName)
{
...
this->sameName = sameName;
}
Otherwise, it's just a matter of taste...

Is it fine to customize C++?

For my projects, I usually define a lot of aliases for types like unsigned int, char and double as well as std::string and others.
I also aliased and to &&, or to ||, not to !, etc.
Is this considered bad practice or okay to do?
Defining types to add context within your code is acceptable, and even encouraged. Screwing around with operators will only encourage the next person that has to maintain your code to bring a gun to your house.
Well, consider the newcomers who are accustomed to C++. They will have difficulties maintaining your project.
Mind that there are many possibilities for the more valid aliasing. A good example is complicated nested STL containers.
Example:
typedef int ClientID;
typedef double Price;
typedef map<ClientID, map<Date, Price> > ClientPurchases;
Now, instead of
map<int, map<Date, double> >::iterator it = clientPurchases.find(clientId);
you can write
ClientPurchases::iterator it = clientPurchases.find(clientId);
which seems to be more clear and readable.
If you're only using it for pointlessly renaming language features (as opposed to the example #Vlad gives), then it's the Wrong Thing.
It definitely makes the code less readable - anyone proficient in C++ will see (x ? y : z) and know that it's a ternary conditional operator. Although ORLY x YARLY y NOWAI z KTHX could be the same thing, it will confuse the viewer: "is this YARLY NOWAI the exact same thing as ? :, renamed for the author's convenience, or does it have subtle differences?" If these "aliases" are the same thing as the standard language elements, they will only slow down the next person to maintain your code.
TLDR: Reading code, any code, is hard enough without having to look up your private alternate syntax all the time.
That’s horrible. Don’t do it, please. Write idiomatic C++, not some macro-riddled monstrosity. In general, it’s extremely bad practice to define such macros, except in very specific cases (such as the BOOST_FOREACH macro).
That said, and, or and not are actually already valid aliases for &&, || and ! in C++!
It’s just that Visual Studio only knows them if you first include the standard header <ciso646>. Other compilers don’t need this.
Types are something else. Using typedef to create type aliases depending on context makes sense if it augments the expressiveness of the code. Then it’s encouraged. However, even better would be to create own types instead of aliases. For example, I can’t imagine it ever being beneficial to create an alias for std::string – why not just use std::string directly? (An exception are of course generic data structures and algorithms.)
"and", "or", "not" are OK because they're part of the language, but it's probably better to write C++ in a style that other C++ programmers use, and very few people bother using them. Don't alias them yourself: they're reserved names and it's not valid in general to use reserved names even in the preprocessor. If your compiler doesn't provide them in its default mode (i.e. it's not standard-compliant), you could fake them up with #define, but you may be setting yourself up for trouble in future if you change compiler, or change compiler options.
typedefs for builtin types might make sense in certain circumstances. For example in C99 (but not in C++03), there are extended integer types such as int32_t, which specifies a 32 bit integer, and on a particular system that might be a typedef for int. They come from stdint.h (<cstdint> in C++0x), and if your C++ compiler doesn't provide that as an extension, you can generally hunt down or write a version of it that will work for your system. If you have some purpose in mind for which you might in future want to use a different integer type (on a different system perhaps), then by all means hide the "real" type behind a name that describes the important properties that are the reason you chose that type for the purpose. If you just think "int" is unnecessarily brief, and it should be "integer", then you're not really helping anyone, even yourself, by trying to tweak the language in such a superficial way. It's an extra indirection for no gain, and in the long run you're better off learning C++, than changing C++ to "make more sense" to you.
I can't think of a good reason to use any other name for string, except in a case similar to the extended integer types, where your name will perhaps be a typedef for string on some builds, and wstring on others.
If you're not a native English-speaker, and are trying to "translate" C++ to another language, then I sort of see your point but I don't think it's a good idea. Even other speakers of your language will know C++ better than they know the translations you happen to have picked. But I am a native English speaker, so I don't really know how much difference it makes. Given how many C++ programmers there are in the world who don't translate languages, I suspect it's not a huge deal compared with the fact that all the documentation is in English...
If every C++ developer was familiar with your aliases then why not, but you are with these aliases essentially introducing a new language to whoever needs to maintain your code.
Why add this extra mental step that for the most part does not add any clarity (&& and || are pretty obvious what they are doing for any C/C++ programmer, and any way in C++ you can use the and and or keywords)

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.