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.

Leif Andersen
  • 21,580
  • 20
  • 67
  • 100
  • 1
    In this example, the problem is different: you use `method()` before it is declared, so it is implicitly assumed to return an `int`. Relying on this dated behavior is somewhat of a bad idea. Change your example to declare `method()` as returning a `const int` to make it more representative. In other words, what you have here is a standard conflict between `const` and non-`const` types, and the fact that the `const` type is the type returned by a function is irrelevant. – Pascal Cuoq Aug 22 '10 at 14:12
  • Does gcc still have the -ansi-pedantic option? It should probably be mandatory for new code. – Paul Tomblin Aug 22 '10 at 14:15
  • Meta-pedantic: `-ansi` and `-pedantic` are separate options ;-) – dirkgently Aug 22 '10 at 14:17
  • meta-meta-pedant: pedantic is checking for standards conformance, and the C standard includes the "dated" behavior. – Ian Aug 22 '10 at 14:21
  • Ok, it's been a long time since I cared, but I'm pretty sure there was an option that enforced the use of prototypes. Isn't that -ansi? – Paul Tomblin Aug 22 '10 at 14:25
  • `-Wimplicit-function-declaration` – CB Bailey Aug 22 '10 at 14:34
  • Ya, it turned out that that was the only problem, I didn't remember to prototype my code, but adding it fixed the issue. – Leif Andersen Aug 22 '10 at 14:49
  • Jumping in a decade later. As of the 1999 edition of the C standard, functions must be declared before they're called. The "implicit `int`" rule was removed. Even today, many compilers still follow it by default, but will probably print a warning. (C99-conforming implementations weren't widely available, if at all, when this question was written.) – Keith Thompson Feb 03 '21 at 20:08

5 Answers5

27

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!

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • `const` makes sense for pointer return types, it indicates that the return value should not be modified. E.g. `const Foo *get_foo(void);` – IluTov Apr 03 '23 at 16:08
4

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
  • 29,161
  • 19
  • 114
  • 169
3

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
  • 179,021
  • 58
  • 319
  • 408
3

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
  • 108,024
  • 16
  • 131
  • 187
  • Thank you, I put the prototype up there, and it solved the problem. – Leif Andersen Aug 22 '10 at 14:24
  • 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 Aug 22 '10 at 14:27
  • 2
    @dirkgently: `-ansi` is equivalent to `-std=c89` it doesn't make sense to use it with `-std=c99`. – CB Bailey Aug 22 '10 at 14:29
  • 2
    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 Aug 22 '10 at 14:38
  • @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 Aug 22 '10 at 14:41
  • @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. – CB Bailey Aug 22 '10 at 14:44
  • @litb: ATM can't find any. I retract my position. – dirkgently Aug 22 '10 at 14:46
  • @litb: Along with notes, sections are renumbered. – dirkgently Aug 22 '10 at 14:52
2

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
  • 4,421
  • 1
  • 20
  • 17
  • 3
    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 Aug 22 '10 at 14:29
  • 2
    http://www.ohse.de/uwe/articles/gcc-attributes.html#func-const Admittedly 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 Aug 23 '10 at 09:30
  • 4
    +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. – Patrick Schlüter Aug 23 '10 at 13:13
  • 3
    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 Aug 24 '10 at 19:25
  • 1
    I think you are confusing C++ const member functions (which use a different syntax than this -- const on the end.) What you are doing here is declaring that the returned value is non modifiable. Returned values are always rvalues in C and in C rvalues are *never* modifiable so actually the const here is useless. To verify this just grab a recent version of llvm (and probably GCC) and compile this with -Weverything flag and the complier will give you a warning... – WayneJ Aug 08 '13 at 20:42
  • WayneJ: I don't C any C++ in the room. Nobody is declaring anything about the constancy of the return value; this is, as you said, implicit. The const attribute in this position declares the purity of the function. Arguably, this need not make any difference and the compiler is being overcautious, but in principle the compiler is allowed to gripe about even the slightest inconsequential difference between declaration and definition. In this case, the declaration was implicit at the call site, and was an imprecise match. – Ian Dec 02 '16 at 17:37
  • Ian, I believe you are incorrect on this point. `const` on a function's return type does not mean that the function is pure. It means that the value returned is of type `const int` rather than `int`, but since a function's result is not an lvalue that has no effect. I can imagine that some compilers might use it for that purpose (it would result in warnings for some code, and compilers can warn about anything they like). Given `const int func(void) { return 42; }`, `gcc -Wextra` says `warning: type qualifiers ignored on function return type [-Wignored-qualifiers]`. – Keith Thompson Feb 03 '21 at 20:05