views:

621

answers:

7

Labelled as homework because this was a question on a midterm I wrote that I don't understand the answer to. I was asked to explain the purpose of each const in the following statement:

const char const * const GetName() const { return m_name; };

So, what is the explanation for each of these consts?

+1  A: 

You have one more const than is syntactically allowed, that code would not compile. Remove the "const" after "char" and before the "*". Also, the last const must come before the function body. It helps to read things like this from right to left.

const char * const GetName() const { return m_name; };

You have a const function (i.e., the function does not alter the state of the class.), which returns a const pointer to a const char.

Ed Swangren
The last const should also be moved before the method body, and to be precise it cannot be a function, but rather a method.
David Rodríguez - dribeas
@dribeas, that's a function. Methods do not exist in C++.
Johannes Schaub - litb
Yes, you are right about the body, but not about the method vs function statement.
Ed Swangren
Downvoted? Why?
Ed Swangren
It should compile fine. Did u check?
Drakosha
In the midterm question, there was a const before the pointer.
4501
@4501: Yes, and it was wrong, so I fixed it. Read the entire post. @Drakosha: Well, I didn't need to, but yes, I did check and no, it would not compile. Please explain what the extra const would mean if it were valid C
Ed Swangren
The "extra" const means the same as the const before "char". The order where const appears isn't relevant. But you cannot write it twice. Same thing why `const const char` is invalid...
Johannes Schaub - litb
Yes Johannes, and I meant to say "valid C++".
Ed Swangren
Ed Swangren - sorry. My mistake, i tried to upvote, but it's not possible (the comment is too old)
Drakosha
A: 

last const:

  • Function does not change the privates of the class

one after last const:

  • It's a constant pointer (i.e. the place it points to is constant)

second const:

  • The function returns a const char (i.e. the content of the char is constant)

First:

  • No idea?

So to be complete: The function returns a constant pointer (always same location) to a constant char(always same content) and the function does not modify the state of the class.

Henri
A const method cannot change ANY members of the class, nor call any non-const methods.
quamrana
@quamrana: A const method can change data members that are static or mutable.
Jerry Coffin
@Jerry: You're right. Let me re-phrase: A const method cannot change any public, protected or private members unless they are static or mutable.
quamrana
+3  A: 

Take them from the right. The one before the ; tells the client this is a design level const i.e. it does not alter the state of the object. (Think of this as a read-only method.)

Okay, now the return value:

const char const *const

This is a constant pointer to okay ... here we go boom! You have an extra const -- a syntax error. The following are equivalent: const T or T const. If you take out a const you get a constant pointer to a constant characters. Does that help?

dirkgently
To clarify, the T in your example is the char, not the char*.So putting it together: const char *const is equivalent to char const * const.
Marcin
This flat out wouldn't work? My prof is a sneaky man, apparently..
4501
constant pointer to a constant characeterS or character?
4501
@4501: No. Try this out in a conforming compiler.
dirkgently
It points to both a constant character and constant characterS. The difference is only made relevant by context since you can get any address in memory by indexing that pointer.
Dan Olson
"you can get any address in memory by indexing that pointer" (a) not validly, and (b) actually not at all on a segmented memory architecture.
Steve Jessop
@dirkgently: If memory serves, GCC produces a diagnostic that says something to the effect of, "Just how const do you want it?"
greyfade
@greyfade: I tried codepad, but wasn't lucky to have such cute messages :)
dirkgently
This code compiles in VC++ 2010
configurator
(And so would `const int const one = 1;`)
configurator
A: 

const(1) char const(2) * const GetName() { return m_name; } const(3);

const char * const result = aaa.GetNAme();

3 - const method, not allowed to change members nor call any non-const methods.

1 - does not allow to modify inside the pointer, i.e. *result = ..

2 - does not allow to move the pointer, i.e. result = NULL

Drakosha
+1  A: 

(1)const char (2)const * (3)const GetName() { return m_name; } (4)const;

  1. The contents of char array is const. This is good when you return pointer of the object member. Since you give pointer to your member for 3rd party, you want to prevent it to be changed from outside.
  2. This form is not used frequently and essentially same as (1)
  3. Our pointer to char array is const, so you can not change where the pointer points too.
  4. it qualifies the GetName() intself, meaning that the method thus not change the class it applied too. Thus it can be called for const object of this type only. This form typically used as GetName(...) const.

As already mentioned in another answers the trick to "remember" it it read from right to left:

  • const T * - pointer to const T
  • T * const - const pointer to T
dimba
Incorrect: (1) and (2) are equivalent. That is, `const T` and `T const` are the same. On the other hand `T const *` and `T * const` are different, one marks the T as constant, the other marks the pointer as constant.
David Rodríguez - dribeas
Upps, you are right, corrected
dimba
+1  A: 

Edit: Looks like I incorrectly pasted the code into Comeau, or it was edited in the original answer to be correct. In either case I'm preserving the answer below as if the code were incorrect.

Comeau online compiler gives these results:

"ComeauTest.c", line 4: error: type qualifier specified more than once
const char const * const GetName() { return m_name; } const; ^

"ComeauTest.c", line 4: warning: type qualifier on return type is meaningless const char const * const GetName() { return m_name; } const; ^

"ComeauTest.c", line 4: error: declaration does not declare anything const char const * const GetName() { return m_name; } const;

What this means is that your statement is malformed.

const char const * const GetName() { return m_name; } const;

The first and second consts mean the same thing. You can't specify the same qualifier more than once so one of these would have to be removed for the code to compile. Both of these consts specify that the values pointed to by the pointer returned by GetName cannot be modified, making code like this invalid:

const char* name = c.GetName();
name[0] = 'a';

The third const specifies that the pointer returned by GetName() itself cannot be modified, but as Comeau points out, this doesn't accomplish anything on a return value because the return value is a copy of the pointer rather than the pointer itself, and can be assigned to a non-const pointer.

The fourth const is misplaced, it should be between GetName and the function body like this:

const char* GetName() const { return m.name; }

This const specifies that no members of the class will be modified during the execution of GetName. Assuming that GetName a member of the class Person, this code would be allowed:

const Person& p;
p.GetName();

Without this const, the above code would fail.

Dan Olson
+1 for pointing out the meaninglessness of making the returned pointer unmodifiable. GCC also warns about it (code still won't compile if you treat warnings as errors :) ). It is important to know what these consts mean, but a function's return type seems to be a rather unfortunate choice for demonstration.
UncleBens
A: 

Given:

const char const * const GetName() const { return m_name; };

The first and second const are equivalent, but only one of them is allowed -- i.e. you can put const before or after the type (char in this case) but only one or the other, not both. Either, however, says that the characters pointed to by the pointer cannot be written to.

The const after the '*' means the pointer returned by the function cannot itself be modified. This is rarely seen on a return type -- what you're returning is a value, which can't be modified in any case (it's normally just assigned to some variable). This can, however, be meaningful in other contexts.

The third const is only allowed on a member function. It says that when this function is called, the this pointer that's received will be a T const * const rather than a T * const, so the member function can only modify static or mutable members of the object, and if it invokes other member functions, they must be const as well. There is, however, a caveat, that it can also cast away the const'ness, in which case it can modify what it sees fit (with the further caveat that if the object was originally defined as const, rather than just having a const pointer to a normal (non-const) object, the results will be undefined).

Jerry Coffin