tags:

views:

148

answers:

5

I was reading some samples of code, and they returned a const int. When I tried to compile the examples code I got errors concerning conflicting return types. So I started searching, thinking that the const was the problem (when I removed it, the code worked fine, not only did it compile, but worked as expected). But I never was able to find information specifically pertaining to a const return type (I did for structures/parameters/etc. etc., but not return types). So I tried writing a piece of code to simply show what const may do. I came up with this:

#include <stdio.h>

int main() {
    printf("%i", method());
}

const int method() {
    return 5;
}

And when I compile this, I get:

$ gcc first.c 
first.c:7: error: conflicting types for ‘method’
first.c:4: note: previous implicit declaration of ‘method’ was here

However, whenever I remove the const, it, as expected, simply prints out a 5, a continues on with life. So, can anyone tell me what const is supposed to mean when used as a return type. Thank you.

+2  A: 

main sees a use of method() without a prototype, so it assumes it returns int. Then you declare it as returning const int. Move the declaration of method() before main, or put a prototype before main.

Paul Tomblin
+3  A: 

Adding the prototype of method() before you call it will fix the error.

const int method();
int main() {
    printf("%i", method());
}

Line 7: error: conflicting types for 'method'

This error tells us that method() was created by the compiler (because it didn't find it) with a different return type than const int (probably int).

Line 4: error: previous implicit declaration of 'method' was here

This other error tells us that in fact the compiler created its own version of method.

Luca Matteis
Yup, it worked. Thank you. I never realized that when methods were located under where they were used, GCC created them. I guess that's another reason why header files are usually included in the source...thanks you.
Leif Andersen
You have not added any prototype before the call. That's a declaration without a prototype.
Johannes Schaub - litb
Should it have been: const int method(void); rather than const int method(); ?
Leif Andersen
+1  A: 

C makes guesses about the return type of a function when you use it before you've told C enough about the function -- it's name, return type, const-ness, and arguments. If those guesses are wrong, you get the error. In this case, they ARE wrong. Use a prototype or move the function above the call.

Oh, and about CONST-ness: this means that the value of a function will be the same if you call it again with the same parameters, and that there should be no (important) side effects. This is useful for optimization, and also it makes a documentary claim that the compiler can enforce concerning parameters. A function promises not to alter a constant, and the compiler can help prevent it.

Ian
Can you please provide a reference that shows that a const qualified return type means that a function has pure behavior, that it produces the same return value for the same input values? I have never heard about that.
Johannes Schaub - litb
http://www.ohse.de/uwe/articles/gcc-attributes.html#func-constAdmittedly this is GNU documentation instead of a standard, but it should get you going. I learned it from the books that came with Borland's C++ compiler way back before windows was mandatory.
Ian
+1 for mentioning the the real `const` interpretation for return values. You should have mentioned that one should better use `__attribute__ ((const))` and `__attribute__ ((pure))` when using gcc. It's imho more explicit.
tristopia
@Ian this is something different and even that page is wrong about it at the end. The language specifies that no `const` shall be specified *on a function type*. The language totally allows it on return types. That page's example applies it to a function types (i.e to the type of a function, *not* to the type of a return type like the text claims at the end). To be more specific, C renders it undefined behavior, and C++ totally forbids it, though C++0x relaxes the rules and says the `const` is just ignored.
Johannes Schaub - litb
+3  A: 

The code you posted should give you an undefined identifier: method at the very least. You need a declaration in scope before you can call the function. Better use:

#include <stdio.h>

const int method() {
    return 5;
}

int main() {
    printf("%i", method());
}

A definition is also a declaration. So, this should fix your error.

dirkgently
Thank you, I put the prototype up there, and it solved the problem.
Leif Andersen
A good set of options to use with gcc is this: `-Wall -ansi -pedantic -std=c99`. Look up the others on GCC's documentation too.
dirkgently
@dirkgently: `-ansi` is equivalent to `-std=c89` it doesn't make sense to use it with `-std=c99`.
Charles Bailey
Why did this get voted up? It is wrong because C does not error when it sees an undefined identifier that looks like a function call. It merely assumes the function is of type int().
JeremyP
@dirkgently As far as i know, ANSI C just differs by notes, no normative wording (i don't remember exactly). Any links?
Johannes Schaub - litb
@dirkgently: That's not what gcc thinks; the info documentation says that there are no technical differences between ANSI X3.159-1989 and ISO/IEC 9899:1990 and that any of the options `-ansi`, `-std=c89` and `-std=iso9899:1990` select this language variant.
Charles Bailey
@litb: ATM can't find any. I retract my position.
dirkgently
@litb: Along with notes, sections are renumbered.
dirkgently
+9  A: 

const makes no sense for return values because return values are rvalues in any case and can't be modified. The error you are getting is from the fact that you use a function before it has been declared so it is implicitly assumed to return int, not const int but then when the method is actually defined, the return type doesn't match the original asssumption. You would get exactly the same error if it were, say, to return double instead of int.

E.g.:

#include <stdio.h>

int main() {
    printf("%i", method());
}

double method() {
    return 5;
}

generates:

$ gcc -std=c99 -Wall -Wextra -pedantic impl.c
impl.c: In function ‘main’:
impl.c:4: warning: implicit declaration of function ‘method’
impl.c: At top level:
impl.c:7: error: conflicting types for ‘method’
impl.c:4: note: previous implicit declaration of ‘method’ was here

See how helpful it is to turn the warning levels up!

Charles Bailey