Declaration is incompatible - c

I was working with IAR Embedded Workbench, using C language.
I had some trouble while dividing my project into the usual main/.h/.c form.
For example, if i create an example.h
#ifndef EXAMPLE_H
#define EXAMPLE_H
void function(int [], int);
#endif
And than an example.c
#include "example.h"
void function (int[] array, int number)
{number = 1; //code
}
It says:
Error[Pe147]: declaration is incompatible with "__interwork __softfp
void function(int *, int)" (declared at line 4 of (path)
Error[Pe141]: unnamed prototyped parameters not allowed when body is present (path)
Error[Pe020]: identifier "number" is undefined (path)
Error while running C/C++ Compiler

The problem is in void function(int [], int). Change to void function(int name[], int) or void function(int *, int). Another error is in int[] array - it has to be int array[] or int * array.

You use wrong syntax. Look at
void function (int array[], int number)
{ number = 1; //code
}

In IAR, you will see this error when declaration and definition will not be matching.
For Ex- if you declare your variable as __ro_placement in .hpp and during initialization in .c or .cpp, if you will not provide __ro_placement with variable, IAR will throw same error.

Related

Getting the error 'conflicting type for function',why?

Here is the below:why it comes out?
#include <stdio.h>
void iniStudentLink(struct STUDENT_LINK * L);
int main(){
return 0;
}
void iniStudentLink(struct STUDENT_LINK * L){
printf("hello world!\n");
}
showing the error : conflicting types for inniStudentLink.
These are the issues that come out of gcc when compiling your code (something it would have been handy to include in your question to make it more complete, that's just advice for the future):
testprog.c:3:28: warning: 'struct STUDENT_LINK' declared inside
parameter list will not be visible outside of
this definition or declaration
void iniStudentLink(struct STUDENT_LINK * L);
^~~~~~~~~~~~
testprog.c:9:28: warning: 'struct STUDENT_LINK' declared inside
parameter list will not be visible outside of
this definition or declaration
void iniStudentLink(struct STUDENT_LINK * L){
^~~~~~~~~~~~
testprog.c:9:6: error: conflicting types for ‘iniStudentLink’
void iniStudentLink(struct STUDENT_LINK * L){
^~~~~~~~~~~~~~
testprog.c:3:6: note: previous declaration of ‘iniStudentLink’ was here
void iniStudentLink(struct STUDENT_LINK * L);
^~~~~~~~~~~~~~
In other words, you are declaring two independent instances of the structure, without actually defining it(a). The reason they are considered independent is because their scope is limited to the actual function where they are being declared.
You can fix this by actually defining it so that the declarations both refer to that definition, such as with (before any other use):
struct STUDENT_LINK { int some_data; };
In other words, this compiles just fine:
#include <stdio.h>
struct STUDENT_LINK { int some_data; };
void iniStudentLink (struct STUDENT_LINK *L);
int main(void) { return 0; }
void iniStudentLink (struct STUDENT_LINK *L){ puts("hi!"); }
(although it may should warn you about the fact you don't actually use L in the function).
(a) The basic difference between declaring and defining in C is this:
Declaring means declaring that something exists without creating it, such as (in your case) stating that you want to pass a pointer-to-it to a function.
Defining it means literally that, defining what it is rather than just that it is.
Example declarations are extern int i; or struct xyzzy; wheras equivalent definitions would be int i; and struct xyzzy { int plugh; };.

Implementation (.c) file conflicts with its own definition (.h) file

I'm trying to create a project that can calculate the weighted average of a class. In this project, I decided to split the declarations and implementations of the header files to separate .h and .c files respectively, then linking them together as object files. This worked well until I created my most recent file, a library of vector functions. When I attempt to build the project, the function signatures from vector.h conflict with the ones from vector.c. Here are the files:
vector.h:
#ifndef VECTOR_H
#define VECTOR_H
void vector_initiate_float(Vector_float *vector);
void vector_append_float(Vector_float *vector, int value);
int vector_get_float(Vector_float *vector, int index);
void vector_set_float(Vector_float *vector, int value, int index);
void vector_double_cap_if_full_float(Vector_float *vector);
void vector_free_float(Vector_float *vector);
#endif /* VECTOR_H */
vector.c:
#include <stdio.h>
#include <stdlib.h>
#include "constants.h"
#include "vector.h"
void vector_append_float(Vector_float *vector, float value){
vector_double_cap_if_full_float(vector);
vector->data[vector->size++] = value;
}
float vector_get_float(Vector_float *vector, int index){
if (index >= vector->size || index < 0) {
printf("Index %d out of bounds for vector of size %d\n", index, vector->size);
exit(1);
}
return vector->data[index];
}
void vector_set_float(Vector_float *vector, int index, float value){
while (index >= vector->size) {
vector_append_float(vector, 0);
}
// set the value at the desired index
vector->data[index] = value;
}
void vector_double_cap_if_full_float(Vector_float *vector){
if (vector->size >= vector->capacity) {
// double vector->capacity and resize the allocated memory accordingly
vector->capacity *= 2;
vector->data = realloc(vector->data, sizeof(int) * vector->capacity);
}
}
void vector_free_float(Vector_float *vector){
free(vector->data);
}
output when I run gcc -c vector.c
vector.c:14:6: error: conflicting types for ‘vector_append_float’
void vector_append_float(Vector_float *vector, float value){
^~~~~~~~~~~~~~~~~~~
In file included from vector.c:11:
vector.h:14:6: note: previous declaration of ‘vector_append_float’ was here
void vector_append_float(Vector_float *, int);
^~~~~~~~~~~~~~~~~~~
vector.c:19:7: error: conflicting types for ‘vector_get_float’
float vector_get_float(Vector_float *vector, int index){
^~~~~~~~~~~~~~~~
In file included from vector.c:11:
vector.h:16:5: note: previous declaration of ‘vector_get_float’ was here
int vector_get_float(Vector_float *, int);
^~~~~~~~~~~~~~~~
vector.c:27:6: error: conflicting types for ‘vector_set_float’
void vector_set_float(Vector_float *vector, int index, float value){
^~~~~~~~~~~~~~~~
In file included from vector.c:11:
vector.h:18:6: note: previous declaration of ‘vector_set_float’ was here
void vector_set_float(Vector_float *, int, int);
As you can see, the function definitions on both files appear to conflict one another, even though this doesn't happen to any other .c and .h pair of files in my project. Searching the internet didn't bear any fruit, so I'm posting here.
As the error messages state, there is a conflict between the declarations of the functions specified and their definitions. Specifically:
vector_append_float has a float for the second parameter but the declaration shows int.
vector_get_float returns float but the declaration says it returns an int.
vector_set_float taks a float for its third parameter but the declaration says it should be an int.
The declaration and definition of a function need to match. Since the definitions seem to be using the correct type, you need to update the declarations in the header file to match.

Assigning a void pointer from function works in one source file, but not in two

So I'm working through this chapter of a sweet modern OpenGL tutorial, and in part of the code I assign a void pointer variable to the return value of a void * function from a second file. I got this error from gcc: initialization makes pointer from integer without a cast. As a test, I tried merging the two files and compiling again. This time, with the function in the same file as where it's called, I get no error.
I was able to reproduce this with three minimal files:
file1.c
void main() {
void *newval = foo();
}
file2.c
#include <stdlib.h>
void *foo() {
void *val;
val = malloc(10);
return val;
}
file3.c
#include <stdlib.h>
void *foo() {
void *val;
val = malloc(10);
return val;
}
void main() {
void *newval = foo();
}
file3.c is just the first two combined. My question is why when I compile one way I get an error, and the other way I get none:
$gcc file1.c file2.cfile1.c: In function ‘main’: file1.c:2:17:
warning: initialization makes pointer from integer without a cast
[enabled by default]$gcc file3.c$
I thought that the file1.c + file2.c combo was identical to file3.c. What am I missing?
In your file1.c, it seems the declaration of void *foo() is missing.
You can either include the header file containing this declaration or add line void *foo() on top of file1.c.
When compiler finds symbol foo followed by ( in main file, and there was no declaration, it assumes foo accepts any number of arguments and returns an int. So you see the warning that int is being converted to a pointer.
But in file file3.c, symbol foo is known as it is a defined function before its first usage so compiler knows that foo returns a pointer and thus no warning.
You need to declare the foo() function so that compiler knows what it is when it compiles file1.c.
Create file2.h and add in it
void *foo();
add include it in file.c
#include "file2.h"
Without declaration, the compiler assumes all unknown functions as returning int, but as your function returns void * and you are assigning it to void *, its trying to assign int to void * and hence you are getting that warning.

warning: initialisation from incompatible pointer type via function table in c

(code examples haven't been tested - just are for example)
I have several declarations like so:
void (* const a[])(void) = {func1, func2};
void func1() {};
void func2() {};
a[0]();
That compiles (if it was real code...) and the should runs func1.
However, if I want to pass arguments such as:
a[0](int 10);
Then I change my declarations:
void (* const a[])(int) = {func1, func2};
void func1(int foo) {};
void func2(int foo) {};
a[0](10);
That also compiles but I get the following warning:
warning: initialisation from incompatible pointer type.
The resulting code also runs fine, but I suspect that the declaration is at fault.
I can find several examples on how to build function tables that do not pass parameters but am struggling to find an example that shows how to do it with one.
Most likely the declarations of func1 and func2 declare them as taking void as a parameter, rather than taking int. You probably have
void func1(void);
void func2(void);
in some header file. Instead, you need
void func1(int);
void func2(int);
This is because the declaration
void (*const a[])(int)
means that a is an array of function pointers taking int and returning void.
At the time you initialize a, func1 and func2 aren't declared, so they have the default type declarations of int (). Declare func1 and func2 before initializing a.
void func1(int);
void func2(int);
void (* const a[])(int) = {func1, func2};
void func1(int foo) {};
void func2(int foo) {};
a[0](10);
I believe that having typedef-s for defining signature of functions make the code more readable. So why not:
typedef void signature_t(int);
void foo1(int);
void foo2(int);
const signature_t* funarray[] = { foo1, foo2 };

C .pc file warning

I have a RefTables.pc file.
When I execute the make command, I get this warning:
RefTables.c:109: warning: type defaults to `int' in declaration of `sqlcxt'
RefTables.c:111: warning: type defaults to `int' in declaration of `sqlcx2t'
RefTables.c:113: warning: type defaults to `int' in declaration of `sqlbuft'
RefTables.c:114: warning: type defaults to `int' in declaration of `sqlgs2t'
RefTables.c:115: warning: type defaults to `int' in declaration of `sqlorat'
How can I remove it?
I am using linux & gcc compiler.
It's been a while since I used Pro*C, but I think you can add a command line option to the proc command line
code=ANSI_C
which will give prototypes for the functions named.
You can remove the warning by specifying the type of the 5 offending declarations. Actually, they must be declared with no type at all, which defaults to int in C (but generates a warning).
Edit: I found on Google this declaration.
extern sqlcxt (/*_ void **, unsigned int *, struct sqlexd *, struct sqlcxp * _*/);
The function has no return type. It should have one. Write it as follows.
extern int sqlcxt (/*_ void **, unsigned int *, struct sqlexd *, struct sqlcxp * _*/);
Or you can manually state in the compiler command line to ignore these warnings. They won't be displayed anymore.
In the future, provide a code snippet along with the warnings so that we have some context to work from. Otherwise we can only guess at what the real problem is.
I'm assuming that sqlcxt, sqlcx2t, etc., are functions. Without seeing the source code, it sounds like you don't have a declaration for those functions in scope before using them.
Here's a short example of what I mean:
int main(void)
{
foo();
return 0;
}
void foo(void)
{
// do something interesting
}
When the compiler sees the call to foo in main, it doesn't have a declaration in scope, so it assumes that foo returns int, not void, and will return a warning similar to what you got above.
If your functions are defined in the same file as they are called, there are two ways around this problem. My preferred way is to define the function before it is used:
void foo(void)
{
// do something interesting
}
int main(void)
{
foo();
return 0;
}
Another way is to have a declaration of the function in scope before calling it:
void foo(void);
int main(void)
{
foo();
return 0;
}
void foo(void)
{
// do something interesting
}
It sounds like these functions are part of a database API; if so, there should be a header file that contains declarations for those functions, and that header should be included in your source file:
/** foo.c */
#include "foo.h"
void foo(void)
{
// do something interesting
}
/** end foo.c */
/** foo.h */
#ifndef FOO_H
#define FOO_H
void foo(void);
#endif
/** end foo.h */
/** main.c */
#include "foo.h"
int main(void)
{
foo();
return 0;
}
/** end main.c */
Hope that helps.

Resources