tags:

views:

438

answers:

2

Say I have this example:

char const * const
foo( ){
   /* which is initialized to const char * const */
   return str;
}

What is the right way to do it to avoid the compiler warning "type qualifier on return type is meaningless"?

+6  A: 

The way you wrote it, it was saying "the returned pointer value is const". But non-class type rvalues are not modifiable (inherited from C), and thus the Standard says non-class type rvalues are never const-qualified (right-most const was ignored even tho specified by you) since the const would be kinda redundant. One doesn't write it - example:

  int f();
  int main() { f() = 0; } // error anyway!

  // const redundant. returned expression still has type "int", even though the 
  // function-type of g remains "int const()" (potential confusion!)
  int const g();

Notice that for the type of "g", the const is significant, but for rvalue expressions generated from type int const the const is ignored. So the following is an error:

  int const f();
  int f() { } // different return type but same parameters

There is no way known to me you could observe the "const" other than getting at the type of "g" itself (and passing &f to a template and deduce its type, for example). In C++0x, you have decltype for getting types from expressions and more, and you can get subtle differences depending how you use it (even GCC gets it wrong):

  int const g();

  decltype(g()) n = 0; // n has type "int const",because g returns int const
  decltype(0, g()) n1 = 0; // n1 has type "int", because expression "0, g()" 
                           // has type int

(decltype gives plain function calls special treatment, and yields its return type, instead of inspecting the resulting expression). In this sense, it's highly confusing to add "const" to the top-level type of non-class types on function return types. Finally notice that "char const" and "const char" signify the same type. I recommend you to settle with one notion and using that throughout the code.

Johannes Schaub - litb
I recommend using always trailing "const" (char const * const), as that is the only way you can use "const" *consistently*. However, I am badly outnumbered on this...
DevSolar
Matthieu M.
@DevSolar, just to clarify: They do not agree with you about the last trailing const. They may agree with your first const that appears after the type name.
Johannes Schaub - litb
@ litb - I didn't get that comment. You mean "they" (the gurus?) disagree with me and, in `int foo() const`, place the const elsewhere? /me confused.
DevSolar
@Dev, i mean they do not agree that `int const f()` is good. They will omit that last trailing const (notice that this is not the same as `int f() const` - it's an entirely different thing). Matthieu (and me too) agrees with you in that `const` after the type is alright (like `int const a = 0;`). But not that it's good as trailing const in function return types (as your comment *may* indicate - so i wanted to clarify).
Johannes Schaub - litb
Ahh... now I get it. Indeed I didn't mean the trailing const of the function return type, but merely to always use *trailing* const **where const is appropriate** (which `int const f()` isn't).
DevSolar
+1  A: 

In C, because function return values, and qualifying values is meaningless.
It may be different in C++, check other answers.

const int i = (const int)42; /* meaningless, the 42 is never gonna change */
int const foo(void); /* meaningless, the value returned from foo is never gonna change */

Only objects can be meaningfully qualified.

const int *ip = (const int *)&errno; /* ok, `ip` points to an object qualified with `const` */
const char *foo(void); /* ok, `foo()` returns a pointer to a qualified object */
pmg
Note that for class types, the `const` for return values is not meaningless, as you are allowed to call modifying member functions on non-const rvalues. (We just had this here with strings the other day: `(s1+s2).append(s3)`.) As usual, litb's answer explains all this both in detail and correctness.
sbi
I meant my answer to deal with C only. Updated to reflect that.
pmg
Ah, he's asked a "C/C++" question. (Strange language, that.) Sorry, I hadn't seen this either.
sbi