How to resolve "conflicting types error" in C?
For the following C code (for swapping two numbers) I am getting the "conflicting types" error for swap
function:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,b;
printf("enter the numbers to be swapped");
scanf("%d%d",&a,&b);
printf("before swap");
printf("a=%d,b=%d",a,b);
swap(&a,&b,si开发者_如何学Pythonzeof(int));
printf("after swap");
printf("a=%d,b=%d",a,b);
getch();
}
void swap(void *p1,void *p2,int size)
{
char buffer[size];
memcpy(buffer,p1,size);
memcpy(p1,p2,size);
memcpy(p2,buffer,size);
return(0);
}
Compiler diagnostics:
<source>:10:6: warning: implicit declaration of function 'swap' [-Wimplicit-function-declaration]
swap(&a,&b,sizeof(int));
^~~~
program:15:6: warning: conflicting types for 'swap'
void swap(void *p1,void *p2,int size)
^~~~
Can anybody tell why that error is coming?
What is the solution for that?
The problem is that swap
was not declared before it is used. Thus it is assigned a "default signature", one which will in this case not match its actual signature. Quote Andrey T:
The arguments are passed through a set of strictly defined conversions.
int *
pointers will be passed asint *
pointers, for example. In other words, the parameter types are temporarily "deduced" from argument types. Only the return type is assumed to beint
.
Aside from that, your code produces a bunch of other warnings. If using gcc
, compile with -Wall -pedantic
(or even with -Wextra
), and be sure to fix each warning before continuing to program additional functionality. Also, you may want to tell the compiler whether you are writing ANSI C (-ansi
) or C99 (-std=c99
).
Some remarks:
- Put spaces after commas.
- Make
main
return anint
.- And make it
return 0
orreturn EXIT_SUCCESS
.
- And make it
- Import the definition of
getch
:#include <curses.h>
.- Or just use
getchar
.
- Or just use
- Import the definition of
memcpy
:#include <string.h>
. - Don't return something in a
void
function. You may want to use
malloc
to allocate a buffer of variable size. That will also work with older compilers:void swap(void *p1, void *p2, int size) { void *buffer = malloc(size); memcpy(buffer, p1, size); memcpy(p1, p2, size); memcpy(p2, buffer, size); free(buffer); }
You need to declare swap before using it. For example, put swap
above main, or add a prototype for swap
like this:
void swap(void *,void *,int);
int main ()
Incidentally main
should be int
not void
and usually it returns the value zero, unless there is an error.
First off, the actual error message wouldn't hurt.
Secondly, making buffer of [size] only works on some compilers (that's a new feature, not all compilers have it yet). Are you sure yours does?
Thirdly, you need to declare swap before calling it. Add a prototype at the top of the file:
void swap(void *p1,void *p2,int size);
You failed to declare your swap
explicitly, forcing the compiler to make assumptions about the function at the point of the call. The compiler, in accordance with C rules, will assume that swap
is
int swap(int *, int *, size_t)
Later you declare your swap as
void swap(void *, void *, int)
which is obviously different from what the compiler assumed. This is the conflict the compiler is telling you about.
Also, your void swap
attempts to return 0
. What were you trying to achieve by that?
P.S. It's int main
, not void main
.
P.P.S. The program is not guaranteed to produce any output if its output does not end in a new-line character.
You may wonder why the program compiles at all without a prototype for swap(), and that's because the compiler is more than a C99 tool. It also compiles C89 and K&R C programs.
C89 added the prototypes. Prior to C89, the compiler didn't need to see the declaration (the prototype) of a function unless it returned something other than int
and the types of the formal parameters were not known to the compiler at all. The compiler just called every function with the types of the actual arguments, which received a set of default argument promotions to simplify things. The programmer would run the lint
utility to cross-check actual and formal parameters. This program is still shipped with the BSD distributions.
K&R programs and their corresponding code styles are still accepted by your compiler, so when it sees a function for which no prototype is available it just goes ahead and calls it anyway.
In this case, you switch paradigms in between the call and the definition of the function. The K&R C assumptions the compiler made about the undeclared function when it had to generate a call turned out not to be valid. Even if you had written the whole program in the K&R style the compiler would have made the same complaints when it found out the real types of the function arguments.
With GCC, this is a warning,
when you dont declare a function before using it, the compiler tries to guess the declaration using the type of call made to that function.Hence the behavior.
Well, it compiles on http://codepad.org (after removing the getch()
, which is irrelevant). Maybe your compiler complains about using memcpy on non-restricted pointers?
In swap()
p1
and p2
are not guaranteed not to be aliases. This is an actual bug waiting to happen - calling swap on &a[i]
and &a[j]
might blow up memcpy
when i==j
. Either use memmove
(which is guaranteed not to blow up on overlapped areas) or declare the pointers restricted
.
精彩评论