Should the 'this' pointer be explicitly used as a rule?

B

beclan

Hello,

I have recently had a discussion with a workmate of mine concerning the
the use of the 'this' pointer.

I argued one should always use the 'this' pointer for a simple reason:
so as to _clearly_ disambiguate member access in the code.

I'd be very much interested in hearing your thoughts on this. Is it
really an unnecessary coding practice as my workmate kept arguing about
or is there some truth in it?

Many thanks.
 
J

Jonathan Lee

I argued one should always use the 'this' pointer for a simple reason:
so as to _clearly_ disambiguate member access in the code.

In my code I find almost everything is member access; I'd have
"this" all over the place. It might make _that one thing_ more
clear, but it would make the code in general a mess.

On the few occasions where there was a genuine confusion, I
use :: to mark the *non-member* functions. It looks a lot
cleaner to me, and happens less often.

--Jonathan
 
G

Gert-Jan de Vos

In my code I find almost everything is member access; I'd have
"this" all over the place. It might make _that one thing_ more
clear, but it would make the code in general a mess.

On the few occasions where there was a genuine confusion, I
use :: to mark the *non-member* functions. It looks a lot
cleaner to me, and happens less often.

Agree, I prefer it when explicit syntax is used to stress the non-
obvious.
this->member is very non-idiomatic and therefore confusing: it
highlights
the trivial. Reserve these visual clues for when something special is
going on.
 
J

James Kanze

In my code I find almost everything is member access; I'd have
"this" all over the place. It might make _that one thing_ more
clear, but it would make the code in general a mess.
On the few occasions where there was a genuine confusion, I
use :: to mark the *non-member* functions. It looks a lot
cleaner to me, and happens less often.

Agreed. Except that :: would generally be SomeNamespace:: in
modern code. The same thing holds for variables, in the rare
case you are using a global variable. The one place ambiguity
might arise is with regards to local variables or function
arguments, but the decaration of these should never be more than
a couple lines above the use, so it should be immediately
visible.

A good naming convention helps, too. A member variable might
have a name like currentState, whereas the function parameter
would be newState; in practice, I've found it worthwhile
formally distinguishing between members and other variables,
using names like myState or m_state for members (and ourState or
s_state for static members), but this is probably only because
I'm not rigorous enough with regards to my naming otherwise; I
feel that it shouldn't be necessary, even if it definitely does
help in my own code.
 
J

Jorgen Grahn

Hello,

I have recently had a discussion with a workmate of mine concerning the
the use of the 'this' pointer.

I argued one should always use the 'this' pointer for a simple reason:
so as to _clearly_ disambiguate member access in the code.

I'd be very much interested in hearing your thoughts on this. Is it
really an unnecessary coding practice as my workmate kept arguing about
or is there some truth in it?

It would have made sense when C++ was a brand new language, but in
2009 it would just look odd -- noone else is doing it.

Many people use special conventions when they name their class
members, though. Foo::foo_ is the one I usually use; Foo::m_foo
is another common one.

/Jorgen
 
M

Michael Tsang

beclan said:
Hello,

I have recently had a discussion with a workmate of mine concerning the
the use of the 'this' pointer.

I argued one should always use the 'this' pointer for a simple reason:
so as to _clearly_ disambiguate member access in the code.

I'd be very much interested in hearing your thoughts on this. Is it
really an unnecessary coding practice as my workmate kept arguing about
or is there some truth in it?

Many thanks.

Completely nonsense.

The purpose of a member function is to access members. (otherwise, you use
functions in namespace instead)
 
J

Jorgen Grahn

Except for functions in a nameless namespace.


I don't know who first invented that convention, but it seems quite
popular, and I really can't understand why. IMO an underscore truly
makes code look more obfuscated than other possible choices. Often you
have to follow that underscore with a dot or a ->, which makes it confusing.

Personally I have got the habit of preceding member variable names
with an 'm', constants with a 'k' and "globals" (well, local to the
current compilation unit) with a 'g'. I have found it does significantly
improve my own understanding of the code months and years later.

Maybe the difference is in how you spell the rest of your members.

I tend to use old Unix-style naming: all lowercase, words separated by
_, e.g. "collation_bits". A _ suffix works fine for me
(collation_bits_) -- I got used to it quickly.

A 'm' prefix feels (subjectively) less neutral -- it interacts in my
brain with the letters in the actual variable name. m_order makes me
think of murder, etc.

Also, it would in practice mean that I would have to add another _
(m_collation_bits) or go CamelCase (mCollationBits) which looks too
much like Java for my taste.

I'm not arguing strongly for trailing _; I just wanted to add a bit
more perspective. The best would have been if C++ had forced us (like
Python and Smalltalk do: self.collation_bits) but it is much too late
for that now, and this->collation_bits cannot be enforced.

/Jorgen
 
J

James Kanze

Maybe the difference is in how you spell the rest of your
members.

Or the font you use. In many fonts, an underscore tends to get
lost. If there are two heavy characters next to it
(alphanumeric, or heavy punctuation like a semi-colon, but not
period, comma or space), you still realize that it's there, but
it's often almost invisible otherwise.
I tend to use old Unix-style naming: all lowercase, words
separated by _, e.g. "collation_bits". A _ suffix works fine
for me (collation_bits_) -- I got used to it quickly.

The "old Unix-style" is nothing to separate words, and using a
maximum of abbreviations (especially dropping voyels).
Something like clltnbt:).
A 'm' prefix feels (subjectively) less neutral -- it interacts
in my brain with the letters in the actual variable name.
m_order makes me think of murder, etc.

What about my_order?

Of course, with really good naming, you don't need anything; the
name contains enough semantic information so that it's obvious
whether it is a member (from the semantics). In practice, I've
found that most people (including myself) don't name that well,
and that the my_ prefix (or our_ for static members) is helpful
in many cases, enough to be worth standardizing on. (But I
admit exceptions: public data members, for example, don't
normally get it.)
Also, it would in practice mean that I would have to add
another _ (m_collation_bits) or go CamelCase (mCollationBits)
which looks too much like Java for my taste.

CamelCase precedes Java by a long shot. It's almost universal
in the telecoms field, at least in Europe, and was long before
anyone had ever heard of Java. I tend to use it by habit, even
in my private code, because of my experience in telecoms.
Esthetically, I think I really prefer the underscore; it does
make for slightly longer names, but not that excessively, and it
looks more like what I would normally write (outside of a
programming context).
I'm not arguing strongly for trailing _; I just wanted to add
a bit more perspective. The best would have been if C++ had
forced us (like Python and Smalltalk do: self.collation_bits)
but it is much too late for that now, and this->collation_bits
cannot be enforced.

I disagree. The best would have been if there were some way of
enforcing good enough names so that the distinction wouldn't be
necessary. In practice, I find too that the real motivation for
the prefix/suffix is laziness: I'm too lazy to create
significantly different names for parameters and members in the
setters. (The real convention should probably be to "prefix"
both: my_state or my_current_state for the member, and
new_state for the parameter, or initial_state if it is a
parameter of a constructor. But as I said, I'm too lazy to do
this consistently.)
 
P

Pavel

Juha said:
Except for functions in a nameless namespace.


I don't know who first invented that convention, but it seems quite
popular, and I really can't understand why. IMO an underscore truly
makes code look more obfuscated than other possible choices. Often you
have to follow that underscore with a dot or a ->, which makes it confusing.
I sometimes think I may be the one to blame ;-). Somewhere around 1993,
you could see a lot of leading underscores used for private variables
and functions. Apparently the confusion was caused by the word
"implementation" (leading underscore is reserved for
"implementation-specific" features and private data members are part of
class's "implementation"). At the same time, Hungarian notation was
widely used so the beginning of the name was "taken" and could not be
used for the purpose with letters (later they abandoned that and started
using 'my' and 'm' prefices for private; I think the Microsoft was first
to change their own conventions, as usual).

Long story short, I started using trailing underscores for that to avoid
non-stanadard leading underscores -- first in my own code and then,
somewhere around 1995, made it a standard convention in my little team.
People called it ugly; I agreed but argued there was no better
alternative and the benefits (knowing the scope at the point of usage)
overweighted the "ugliness". During that time, I think I went little
extreme: also called private member functions and sometimes even
protected members with same convention.

Now you can see these all over the place but I don't think I saw another
organization's code with this convention before 1999 or so (and the
first time that was Java code, I think). Of course, other people could
come to the same convention independently.

I still agree these are ugly but still don't know a better convention. I
disagree they are obscure. In my perception, extra tokens, like
additional "this->", add complexity (that is, obscure) but extra
characters in one token don't. This is all of course a matter of
personal perception.

Personally I have got the habit of preceding member variable names
with an 'm', constants with a 'k' and "globals" (well, local to the
current compilation unit) with a 'g'. I have found it does significantly
improve my own understanding of the code months and years later.

I banned introducing new globals and the names of pre-existing ones
(some globals always preexist your code :) -- that's just how they are)
were out of our control.

-Pavel
 
P

Pavel

Juha said:
Except for functions in a nameless namespace.


I don't know who first invented that convention, but it seems quite
popular, and I really can't understand why. IMO an underscore truly
makes code look more obfuscated than other possible choices. Often you
have to follow that underscore with a dot or a ->, which makes it confusing.
I sometimes think I may be the one to blame ;-) . Somewhere around
1993, you could see a lot of leading underscores used for private
variables and functions. Apparently the confusion was caused by the word
"implementation" (leading underscore is reserved for
"implementation-specific" features and private data members are part of
class's "implementation"). At the same time, Hungarian notation was
widely used so the beginning of the name was "taken" and could not be
used for the purpose with letters (later they abandoned that and started
using 'my' and 'm' prefices for private; I think the Microsoft was first
to change their own conventions, as usual).

Long story short, I started using trailing underscores for that to avoid
non-stanadard leading underscores -- first in my own code and then,
somewhere around 1995, made it a standard convention in my little team.
People called it ugly; I agreed but argued there was no better
alternative and the benefits (knowing the scope at the point of usage)
overweighted the "ugliness". During that time, I think I went little
extreme: also called private member functions and sometimes even
protected members with same convention.

Now you can see these all over the place but I don't think I saw another
organization's code with this convention before 1999 or so (and the
first time that was Java code, I think). Of course, other people could
come to the same convention independently.

I still agree these are ugly but still don't know a better convention
(some people still like to use the beginning of the names for different
purposes). I disagree they are obscure. In my perception, extra tokens,
like additional "this->", add complexity (that is, obscure) but extra
characters in one token usually don't. This is all of course a matter of
personal perception.
Personally I have got the habit of preceding member variable names
with an 'm', constants with a 'k' and "globals" (well, local to the
current compilation unit) with a 'g'. I have found it does significantly
improve my own understanding of the code months and years later.

We absolutely banned introducing new globals and the names of
pre-existing ones (some globals always preexist your code :) --
that's just how they are) were out of our control.

-Pavel
 
P

Pavel

James said:
Or the font you use. In many fonts, an underscore tends to get
lost. If there are two heavy characters next to it
(alphanumeric, or heavy punctuation like a semi-colon, but not
period, comma or space), you still realize that it's there, but
it's often almost invisible otherwise.


The "old Unix-style" is nothing to separate words, and using a
maximum of abbreviations (especially dropping voyels).
Something like clltnbt:).


What about my_order?

Of course, with really good naming, you don't need anything; the
name contains enough semantic information so that it's obvious
whether it is a member (from the semantics). In practice, I've
found that most people (including myself) don't name that well,
and that the my_ prefix (or our_ for static members) is helpful
in many cases, enough to be worth standardizing on. (But I
admit exceptions: public data members, for example, don't
normally get it.)


CamelCase precedes Java by a long shot. It's almost universal
in the telecoms field, at least in Europe, and was long before
anyone had ever heard of Java. I tend to use it by habit, even
in my private code, because of my experience in telecoms.
Esthetically, I think I really prefer the underscore; it does
make for slightly longer names, but not that excessively, and it
looks more like what I would normally write (outside of a
programming context).


I disagree. The best would have been if there were some way of
enforcing good enough names so that the distinction wouldn't be
necessary. In practice, I find too that the real motivation for
the prefix/suffix is laziness: I'm too lazy to create
significantly different names for parameters and members in the
setters. (The real convention should probably be to "prefix"
both: my_state or my_current_state for the member, and
new_state for the parameter, or initial_state if it is a
parameter of a constructor. But as I said, I'm too lazy to do
this consistently.)
BTW, there used to be a convention to use an 'a' article for parameters:
void draw(Shape aShape){...}. That was not too bad except that sometimes
it read ugly for native English speakers (e.g. string join(const
vector<string> &aParts) or copy(Iterator aBegin, Iterator anEnd,
Iterator aDestination)).

Some drawbacks of encoding scope and accessibility into "good names" (I
assume you mean the names encoded as self-explaining short phrases):

1. Laziness is the fact of life (and the driving engine of the progress
at that); if even you with your rigor admit being lazy, how can you
reasonably expect from others not to?

2. The accessibility and scope of a name are "always there" whereas
semantics changes and may on an occasion clash with whatever "wordy"
naming convention you choose. For example, if a "Game" class must have
"myLastMove" and "hisLastMove" data members, the convention to indicate
private members with "my" prefix would lead to "myMyLastMove" and
"myHisLastMove" -- not too clear. I would argue that myLastMove_ and
hisLastMove_ is the lesser evil. The point heere is that the convention
is better to stand out syntactically from the "domain-level" meaning.
And, it's better be short.

I would agree that enforcement at the language level would help. Of
course it is difficult to imagine how "good names" in common sense of
the phrase could be enforced but I would be all for enforcing leading or
trailing special characters like '$' or '@' to indicate the *syntactic*
properties of a name (such as the scope or accessibility or whether the
name is a reference). In this regard I think, Perl (and some old macro
languages of IBM) offer a lot of worthy ideas to consider.


-Pavel
 
J

James Kanze

[...]
BTW, there used to be a convention to use an 'a' article for
parameters: void draw(Shape aShape){...}. That was not too bad
except that sometimes it read ugly for native English speakers
(e.g. string join(const vector<string> &aParts) or
copy(Iterator aBegin, Iterator anEnd, Iterator aDestination)).

I've seen that one, too. For plurials, they used some, e.g.:
someParts (instead of aParts).
Some drawbacks of encoding scope and accessibility into "good
names" (I assume you mean the names encoded as self-explaining
short phrases):
1. Laziness is the fact of life (and the driving engine of the
progress at that); if even you with your rigor admit being
lazy, how can you reasonably expect from others not to?

Realistically, I don't expect it, but the projects I've worked
on where the programmers have come closest to the ideal are also
those which ended up the most robust (and were the least
expensive to develop in the long run).
2. The accessibility and scope of a name are "always there"
whereas semantics changes and may on an occasion clash with
whatever "wordy" naming convention you choose.

This is a serious problem. If the semantics of a parameter
changes, you have to examine every call site, to be sure that
the arguments passed correspond to the new semantics.
Realistically, this means that you must change the name of the
function, or possibly the types in a way that won't compile, so
that you get a compiler error. If you're providing lower level
functions for other users, you may even have to continue to
provide the old function, with the old semantics, along side the
new one.
 
J

James Kanze

I sometimes think I may be the one to blame ;-). Somewhere
around 1993,

The convention is older than that. I know I heard about it
about then, as an already established convention. And I know of
code using it as early as 1995.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top