views:

381

answers:

2

I have a small program to test passing char* pointers in and out of functions. When I compile with cc, I get warning and errors saying I have conflicting types even though all my variables are char* . Please enlighten

#include <stdio.h>

main()
{
    char* p = NULL;

    foo1(p);
    foo2();
}

void foo1(char* p1)
{
}

char* foo2(void)
{
    char* p2 = NULL;

    return p2;
}

p.c:11: warning: conflicting types for ‘foo1’
p.c:7: warning: previous implicit declaration of ‘foo1’ was here
p.c:15: error: conflicting types for ‘foo2’
p.c:8: error: previous implicit declaration of ‘foo2’ was here
+16  A: 

You need to prototype your functions before the main() function.

example:

void foo1(char *p1);
char* foo2(void);

int main(.......

Or just put the bodies for those functions above the main function.

ghills
Thanks, I overlooked that.Confusing error messages though.
+3  A: 

As ghills said, to fix the error, move the function definitions above main() or put function prototypes there.

The reason for the error is that when the compiler sees:

foo1(p);
foo2();

before it sees either a declaration or definition of foo1() and foo2(), it assumes the return type of those functions is int. In the early days of C, int was considered to be a reasonable default return type (there was no void type in the earliest versions of C). Nowadays, omitting the return type is considered bad practice and compilers complain about it.

Don McCaughey
Not just the return type, but the type of the arguments are assumed to be int as well. This causes problems when (for example) passing pointers to un-prototyped functions, when sizeof(void *) != sizeof(int)...
ephemient
@ephemient, the type of the arguments are not assumed to be anything in particular. if there is no declaration, the function is implicitly declared as "extern int name();" (with C89). And more importantly, in C99 it's an error to omit a function declaration or to omit the return type. Arguments are promoted (char->int,float->double,...) and if the promoted types do not match the actual parameter types, then behavior is undefined.
Johannes Schaub - litb
@litb: I do remember that (at the very least) passing pointers to unprototyped variadic functions had significant issues in practice. I don't recall the particulars of what ANSI C/C89/C99 specify are, so I'll defer to you on that.
ephemient
@ephemient, since the function will be declared as "extern int name();", if the function is actually variadic, like "extern int name(int a, ...);" then undefined behavior will happen. For example, printf will always have to have a prototype declared prior to its call. But calling non-variadic functions without prototype is fine as long as the arguments have the right type in C89 (although this is deprecated).
Johannes Schaub - litb
Another problem is passing pointers to a function having a parameter with type void* but no prototype. You have to convert explicitly to void*, since the compiler can't do that for you since it doesn't know the types the arguments should have.
Johannes Schaub - litb