192

What is the difference between the arguments in:

int foo1(const Fred &arg) {
...
}

and

int foo2(Fred const &arg) {
...
}

? I don't see this case covered in the parashift FAQ.

eisbaw
  • 2,678
  • 2
  • 19
  • 18
  • 6
    http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.8 – Oliver Charlesworth Sep 12 '10 at 11:27
  • 2
    is this a question about style? "const Fred" sounds good in english, but "Fred const" looks better to me. – LatinSuD Sep 12 '10 at 11:28
  • 1
    On a related note, is there any reason one should prefer `Fred const &arg` over `Fred const& arg`? I like the latter better because `const&` is a unit there meaning "constref", and the name `arg` is separated by a blank from all the type specifiers. – Frank Sep 12 '10 at 12:34
  • 5
    @dehmann: But `int const& ref` doen't mean 'const ref' but 'ref to const'. – Cedric H. Sep 12 '10 at 13:12
  • 1
    Duplicate of: http://stackoverflow.com/questions/2640446/why-do-some-people-prefer-t-const-over-const-t – Michael Aaron Safyan Sep 12 '10 at 21:10
  • @OliverCharlesworth link is broken, I believe it moved to here: https://isocpp.org/wiki/faq/const-correctness#const-ref-alt – Gunther Struyf Jun 15 '16 at 08:56

7 Answers7

163

Behavior

There is no semantic difference between const T& and T const&; the language treats them as the same type. (The same thing applies to const T* and T const*.)

As a matter of style

Regarding which you should prefer stylistically, however, I'll dissent from a lot of the other answers and prefer const T& (and const T*):

  • const T& is the style used in Stroustrup's The C++ Programming Language book.
  • const T& is the style used in the C++ standard itself.
  • const T* is the style used in K&R's The C Programming Language book.
  • const T* is the style used in the C standard.
  • Due to the above factors, I think const T&/const T* have way more inertia than T const&/T const*. const T&/const T* empirically seem way more common to me than T const&/T const* in all of the C++ and C code that I've seen. I think following common practices is more readable than dogmatically adhering to right-to-left parsing rules.
  • With T const*, it seems easier to misplace the * as T* const (especially if people aren't as accustomed to it). In contrast, const* T is not legal syntax.

What about the right-to-left parsing rule?

Regarding the whole right-to-left parsing argument that people seem to love to use: as I mentioned in a comment to another answer, const T& reads fine right-to-left too. It's a reference to a T constant. "T" and "constant" each can work as an adjective or a noun. (Additionally, reading T const* right-to-left can be ambiguous since it could be incorrectly interpreted as "pointer constant to T" instead of as "pointer to constant T".)

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
  • 5
    +1, agreed. When reading code it's easier to spot a const if the line begins with const. The right-left rule is really only needed when manually parsing especially hairy type declarations. Why not optimize for the most common case? Besides, IMHO if you write type declarations so you need to manually run an FSM in your head you're doing it wrong. – Andreas Magnusson Nov 30 '10 at 11:05
  • 2
    -1. Regardless of how justified your conclusions are and how much I personally agree to them, they are *not answering the asked question* directly. This makes the second-most answer to a simple question appear like an off-topic gibberish about some messy underwater machinery, with no conclusions, no direct answer — nothing. You'll get my upvote when you add a simple clear summary stating "**No, there is no semantic difference between both syntaxes**, but there are some stylistical considerations as follows...". And only then all those bullets. – ulidtko Apr 11 '13 at 09:11
  • 1
    IMO the reason `const T&` reads better, is that: 1- We read code from left to right. And 2- When describing a new concept we start from the more general concept to the more specific. Here, the `const` keyword is more general as it sections the variable space into two categories, whereas the type specifier sections it into many. – pooya13 Apr 04 '19 at 21:51
  • "pointer to" should stay together. So there is no ambiguity for `T const*` – Dexter May 31 '20 at 13:06
  • @Dexter While "pointer to" *should* stay together, it's another thing to remember and potentially get wrong. – jamesdlin Sep 21 '20 at 22:13
  • @jamesdlin what is there exactly to remember? You read it left to right, as it is written. `pointer to const T`. Meanwhile `const T*` has something to remember, the fact that const, if there's nothing on the left, applies to the right, and now tell me, is it constant pointer to T, or is it constant T? How far to the right does const extend to? Why does it go left to right in the first place, against everything else? If we go backwards, then we go backwards all the way. Otherwise you have something to actually remember, because its not as obvious as just reversing a direction. –  Dec 11 '21 at 12:51
  • @Sahsahae Huh? 1. `T const*` is *not* read left-to-right as written. You have to read it right-to-left, and as I already explained, you have to remember that it's "pointer to constant T" and not "pointer constant to T". 2.Regarding your "meanwhile" remark, as I *also* already explained in my answer, you *do* read `const T*` right-to-left (i.e., "backwards all the way"): "pointer to T constant". – jamesdlin Dec 11 '21 at 16:49
  • @jamesdlin you don't have to remember anything, you literally only need to connect `* -> const -> T`. That's what reading right to left means. If you mean you have to ***unlearn*** that const associates with right instead of left sometimes, well that's the problem of the opposite way of writing it, which is what causes const to apply to the right, because there's nothing on the left `const T*`, that's why they're unambiguously equal, except harder to grok to people who don't know the rules. and fail to read this whether they read from left or from right. C++ is read right to left otherwise... –  Dec 11 '21 at 23:42
143

No difference as const is read right-to-left with respect to the &, so both represent a reference to an immutable Fred instance.

Fred& const would mean the reference itself is immutable, which is redundant; when dealing with const pointers both Fred const* and Fred* const are valid but different.

It's a matter of style, but I prefer using const as a suffix since it can be applied consistently including const member functions.

Sean Fausett
  • 3,710
  • 1
  • 23
  • 17
  • Then what is a point to make `std::is_const::value` be `false`? – abyss.7 Mar 15 '19 at 14:30
  • @abyss.7 that's a reference to `const T`; the reference is mutable. – Sean Fausett Mar 15 '19 at 20:55
  • 1
    How is the reference mutable if, by definition, it cannot be re-bound, and this is exactly what is discussed by this question and the answers to it - the notion of `T& const` being redundant? It was a very valid question about `is_const`, and one I also would like to know the answer to. – Violet Giraffe Dec 21 '20 at 21:40
  • @VioletGiraffe indeed the reference cannot be re-bound so in that sense references are not mutable. It would be better to simply say that references ignore `const` qualifiers on the reference itself: "Reference types cannot be cv-qualified at the top level; there is no syntax for that in declaration, and if a qualification is added to a typedef-name or decltype specifier, or type template parameter, it is ignored." (See [cppreference.com](https://en.cppreference.com/w/cpp/language/reference)) – Sean Fausett Jan 18 '21 at 04:00
14

Though they are one and the same, to retain consistency with the RIGHT-LEFT rule about parsing C and C++ declarations, it is better to write Fred const &arg

Also refer this for developing more understanding about declarations, qualifiers and declarators.

Chubsdad
  • 24,777
  • 4
  • 73
  • 129
  • 1
    I prefer the suffix, because it works better with `typedef` expansion. Example: `typedef int* pointer;`, `const pointer` **is not** `const int*`, it's `int* const`. The suffix form is not awkward. – Matthieu M. Sep 12 '10 at 16:49
  • 4
    IMO `const T&` reads fine right-to-left too; it's a reference to a T constant. `T` and `constant` each can work as an adjective or a noun. – jamesdlin Sep 12 '10 at 18:08
8

Both work, and here is the explanation from the man who wrote it.
To quote him:

Why? When I invented "const" (initially named "readonly" and had a corresponding "writeonly"), I allowed it to go before or after the type because I could do so without ambiguity.

kinokijuf
  • 968
  • 1
  • 11
  • 33
default
  • 11,485
  • 9
  • 66
  • 102
5

No difference, both are syntactically and semantically same.

Prasoon Saurav
  • 91,295
  • 49
  • 239
  • 345
4

References doesn't work the same way as pointers: for pointers you can have 'const pointers' (type * const p) and 'pointer to const' (const type * p or type const * p).

But you don't have this for references: a reference will always refer to the same object; in that sense you can consider that 'references' are 'const references' (the same way you can have 'const pointers').

Therefore something like 'type & const ref' is not legal. You can only have 'reference to type' (type &ref) and 'reference to constant type' (const type &ref or type const &ref; both are exactly equivalent).

One last thing: even if const type sounds more correct in English, writing type const allows a more systematic understanding of declarations "right to left" : int const & ref can be read has 'ref is a reference to a constant int'. Or more complicated example: int const * const & ref, ref is a reference to a constant pointer to a constant int.

Conclusion: in your question, both are exactly equivalent.

Cedric H.
  • 7,980
  • 10
  • 55
  • 82
3

No difference http://c-faq.com/ansi/constptrconst.html

Nirocfz
  • 31
  • 2