7

I know the topic of pass by reference vs. pass by pointer is heavily covered... Pretty sure I understood all the nuances until I read this:

http://carlo17.home.xs4all.nl/cpp/const.qualifier.html

which reads (in case the link goes dead)

The prototype for foobar can have any of the following footprints:
void foobar(TYPE);      // Pass by value
void foobar(TYPE&);     // Pass by reference
void foobar(TYPE const&);   // Pass by const reference

Note that I put the const to the right of TYPE because we don't know if TYPE (this is not a template parameter, but rather for instance a literal char*) is a pointer or not!

what does the author mean by "Note that I put the const to the right of TYPE because we don't know if TYPE ... is a pointer or not!"

Everything I've read on this topic has been consistent in saying that:

void foodbar(TYPE const &)

is equivalent too

void foobar(const TYPE &)

If I understand the author correctly, s/he is saying that:

const int *X vs int * const X where pointer, X itself is const vs. what X points to is const?

If so, is this true?

Eric
  • 1,697
  • 5
  • 29
  • 39
  • see http://stackoverflow.com/questions/2640446/why-do-some-people-prefer-t-const-over-const-t – ognian Jun 04 '11 at 05:26
  • 3
    The author misunderstands the language (the two are *identical*), and I honestly have no idea what he's trying to say. Yet another reason to get a book and not try to learn from some online article. – GManNickG Jun 04 '11 at 05:26
  • 1
    Buying a book doesn't guarantee that you have a quality resource, even popular books: http://www.seebs.net/c/c_tcn4e.html – user505255 Jun 04 '11 at 05:31
  • in case you missed what I wrote, here it is again, "Everything I've read on this topic has been consistent." This includes several books. In particular "Professional C++" by Nicholas A. Solter, Scott J. Kleper on page 332 reads, "Remember that const int &zRef is equivalent to int const &zRef." http://www.amazon.com/Professional-C-Programmer-Nicholas-Solter/dp/0764574841 – Eric Jun 04 '11 at 05:37

3 Answers3

9

If TYPE is a #define for something like int*, the placement of const does matter. In that case you will get const int* or int* const depending on the placement of const.

If TYPE is a typedef or a template parameter, the const will affect the whole type either way.

To me this looks more like another argument against macros, rather than a need for some specific style in declarations.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
1

Looking at the C++ FAQ Lite (as the article suggests), you read pointer declarations from right-to-left. So if TYPE is a pointer, the placement of the * does make a difference. Follow the link for the full story.

Gnawme
  • 2,321
  • 1
  • 15
  • 21
  • Only if TYPE is a **macro** that expands to a pointer type. If it's a typedef or a template parameter, then `const TYPE&` means the same thing as `TYPE const&`, even if the actual type is a pointer type. That's part of the reason for using typedefs :) – Karl Knechtel Jun 04 '11 at 06:22
  • The reference in the original question says: "Consider an arbitrary type TYPE." The author plainly was not referring to a macro. – Gnawme Jun 04 '11 at 06:24
  • 1
    So given that, the answer is simply wrong: a typedef'd type is treated as a unit, and you can't end up inserting `const`s into the middle of that type declaration. `const TYPE&` means the same as `TYPE const&`, even if TYPE could be "broken up" to offer another position for the `const` keyword to go. – Karl Knechtel Jun 04 '11 at 06:30
  • Instead of TYPE, let's use Fred (to avoid the connotations of an all-caps type -- which screams MACRO! to me). So, to summarize from the FAQ: Fred const* p means "p points to a constant Fred": the Fred object can't be changed via p. Fred* const p means "p is a const pointer to a Fred": you can't change the pointer p, but you can change the Fred object via p. Fred const* const p means "p is a constant pointer to a constant Fred": you can't change the pointer p itself, nor can you change the Fred object via p. So for a pointer type, the placement of const relative to the type does matter. – Gnawme Jun 04 '11 at 18:27
  • To the extent that "the placement of const relative to a pointer type does matter", it is not valid to use `Fred` to describe a pointer type. If `Fred` is a typedef for int\*, then `const Fred&` means the same as `Fred const&`, which means the same as `int* const&`. It **does not** mean `const int*&`, which is the same as `int const*&`. – Karl Knechtel Jun 06 '11 at 22:34
  • An illustration: `typedef int* Fred; int x; const Fred referred_to = &x;` <-- int* const = const (int*), not (const int)* `const int*& f = referred_to;` <-- error: invalid initialization of reference of type 'const int*&' from expression of type 'int* const' `int* const& g = referred_to; /* ok */ const Fred& h = referred_to; /* ok */ Fred const& i = referred_to; /* also ok! */` As you can see, the placement of the 'const' relative to the type **def** does **not** matter. – Karl Knechtel Jun 06 '11 at 22:35
  • As I said, if `TYPE` (or `FRED`, or `Fred`, written by someone who does not respect conventions) is a macro, **then** the position does matter, because the macro will be textually substituted before the overall type is parsed. – Karl Knechtel Jun 06 '11 at 22:38
0
void foobar(TYPE const&);   // Pass by const reference

If TYPE is a pointer to a type ABC, then

void foobar(ABC* const&)

is different to

void foobar(const ABC* &)

I believe that is all the author is getting at.

EDIT

This also applies if the typedef is a pointer

typedef SomeStruct* pSomeStruct;
void foobar(pSomeStruct* const &); // const reference to a pointer
                                   // to a pointer to SomeStruct
void foobar(const pSomeStruct* &); // reference to a pointer
                                   // to a const pointer to const SomeStruct
Chris Bednarski
  • 3,364
  • 25
  • 33
  • For this to make sense, you must be much more precise about what you mean by "TYPE **is** a pointer...". See my comment on the other answer. – Karl Knechtel Jun 04 '11 at 06:23
  • @Karl: I do get your point about typedefs being a unit. However, what I said makes sense even if there's a pointer to a typedefed type. – Chris Bednarski Jun 04 '11 at 21:36