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

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.

Related

Using struct variables in functions - Conflicting types

I'm trying to pass struct variables to a function, but I receive:
error: conflicting types for 'referenzspannung'
void referenzspannung(struct ADMESSUNG *mess) {
^~~~~~~~~~~~~~~~
In my measure.h I wrote the prototype:
void referenzspannung(struct ADMESSUNG *mess);
and in the measure.c there is the struct+function:
struct ADMESSUNG {
unsigned long Coderef;
double Uref;
double Stcal;
double Offset;
unsigned long Temperaturcode;
double Temperaturavin;
double RTD;
double R;
double Tempwert;
unsigned long Phcode;
double Phavin;
double Stprobe;
double PHWert;
};
struct ADMESSUNG mess;
void referenzspannung(struct ADMESSUNG *mess) {
AD7793_SetIntReference(AD7793_REFSEL_INT);
AD7793_SetExcitDirection(AD7793_DIR_IEXC1_IOUT2_IEXC2_IOUT1);
AD7793_SetExcitCurrent(AD7793_EN_IXCEN_210uA);
AD7793_SetChannel(AD7793_CH_AIN3P_AIN3M);
mess->Coderef = AD7793_ContinuousReadAvg(50);
mess->Uref = ((mess->Coderef / 8388608) - 1) * 1.17; // code in voltage
}
In my main.c I call the function then:
referenzspannung(struct ADMESSUNG *mess);
Does anyone see a mistake? I think I did everything in the right order and I have the syntax from multiple websites.
Move the definition struct ADMESSUNG {...} to your .h file.
The compiler makes assumptions about what the struct looks like when it encounters void referenzspannung(struct ADMESSUNG *mess); with out knowing what the struct looks like.
The compiler would warn you about these assumptions. In gcc use -Wall to get all warnings.
The instance declaration struct ADMESSUNG mess; needs to be in the main.c to be visible where it is referenced or should be in the .h with an extern modifier.
The function call should reference the struct instance referenzspannung(&mess); as it is not a pointer.

Makefiles and structures in C

EDIT: To try and make things easier for the kind souls trying to help me, here are a couple links that should make things more clear:
Pre-makefile repl
Post-makefile repl
A little background on the assignment: We are supposed to take a program we wrote last week and break up the separate functions into their own files and use a makefile to compile and link and all that stuff. This is my original program (basically, it reads a file of name number and stores them in a struct, then uses the command line arguments to search for a name).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _data {
char* name;
long number;
};
int SCAN(FILE *(*input)) {
int lines = 0;
char word[50];
long num = 0;
while (1) {
fscanf(*input,"%s %ld",word, &num);
lines++;
if (feof(*input)) break;
}
return lines;
}
struct _data *LOAD(FILE *input, int size) {
char* line = NULL;
size_t len = 0;
int i=0;
rewind(input);
struct _data *book = calloc(size,sizeof(struct _data));
for (i = 0;i<size;i++) {
getline(&line, &len, input);
book[i].name = calloc(len+1,sizeof(char));
strcpy(book[i].name,strtok(line," "));
book[i].number = atoi(strtok(NULL, " "));
}
return book;
}
void SEARCH(struct _data *BlackBook, char *name, int size) {
int i;
for (i=0;i<size;i++) {
if (strcmp(name,BlackBook[i].name) == 0) {
printf("*******************************************\n");
printf("The name was found at the %d entry.\n",i+1);
printf("*******************************************\n");
break;
}
//If we reach the end of the array and name was not found
if (i == size-1) {
printf("*******************************************\n");
printf("The name was NOT found.\n");
printf("*******************************************\n");
}
}
}
void FREE(struct _data *BlackBook, int size) {
int i;
for (i=0;i<size;i++){
free(BlackBook[i].name);
}
free(BlackBook);
}
//MAIN DRIVER ===================
int main(int argv, char** argc) {
int size;
char* filename = "hw5.data";
FILE *input = fopen(filename,"r");
size = SCAN(&input);
struct _data *phone_book = LOAD(input,size);
fclose(input);
//Check a name is given. If so, search
if (argv < 2) {
printf("*******************************************\n");
printf("* You must include a name to search for. *\n");
printf("*******************************************\n");
} else {
SEARCH(phone_book, argc[1], size);
}
FREE(phone_book,size);
return 0;
}
When I make my makefile, I can get the SCAN and LOAD functions to work appropriately. But, when I try to put either SEARCH or FREE into their own files, my compiler freaks out and I get warnings like:
In file included from hw6-free.c:1:0:
hw6-free.h:9:18: warning: ‘struct _data’ declared inside parameter list
void FREE(struct _data *BlackBook, int size);
^
hw6-free.h:9:18: warning: its scope is only this definition or declaration, which is probably not what you want
hw6-free.c:3:18: warning: ‘struct _data’ declared inside parameter list
void FREE(struct _data *BlackBook, int size) {
^
hw6-free.c:3:6: error: conflicting types for ‘FREE’
void FREE(struct _data *BlackBook, int size) {
^
In file included from hw6-free.c:1:0:
hw6-free.h:9:6: note: previous declaration of ‘FREE’ was here
void FREE(struct _data *BlackBook, int size);
^
hw6-free.c: In function ‘FREE’:
hw6-free.c:6:5: error: invalid use of undefined type ‘struct _data’
free(BlackBook[i].name);
^
hw6-free.c:6:19: error: dereferencing pointer to incomplete type ‘struct _data’
free(BlackBook[i].name);
^
Makefile:20: recipe for target 'hw6-free.o' failed
make: *** [hw6-free.o] Error 1
And reading through it, it looks like the fact my program takes a struct as an argument is my main problem? My 'post-makefile' program looks like:
#include "hw6-main.h"
int main(int argv, char** argc) {
int size;
char* filename = "hw5.data";
FILE *input = fopen(filename,"r");
size = SCAN(&input);
struct _data *phone_book = LOAD(input,size);
fclose(input);
//Check a name is given. If so, search
if (argv < 2) {
printf("*******************************************\n");
printf("* You must include a name to search for. *\n");
printf("*******************************************\n");
} else {
SEARCH(phone_book, argc[1], size);
}
FREE(phone_book,size);
return 0;
}
And my makefile looks like:
DEP = hw6-scan.o hw6-load.o hw6-search.o hw6-free.o hw6-main.o
HDR = hw6-scan.h hw6-load.h hw6-search.h hw6-free.h hw6-main.h
NAME = output
all: $(NAME)
output: $(DEP) $(HDR)
gcc $(DEP) $(HDR) -o $(NAME)
hw6-scan.o: hw6-scan.c
gcc -c hw6-scan.c
hw6-load.o: hw6-load.c
gcc -c hw6-load.c
hw6-search.o: hw6-search.c
gcc -c hw6-search.c
hw6-free.o: hw6-free.c
gcc -c hw6-free.c
hw6-main.o: hw6-main.c
gcc -c hw6-main.c
clean:
rm *.o *.gch *.out output testfile
As an example, my hw6-free.c and hw6-free.h look like:
#include "hw6-free.h"
void FREE(struct _data *BlackBook, int size) {
int i;
for (i=0;i<size;i++){
free(BlackBook[i].name);
}
free(BlackBook);
}
and
#include <stdio.h>
#include <stdlib.h>
void FREE(struct _data *BlackBook, int size);
respectively.
And, finally, I defined the struct in the hw6-load.h file, along with a function prototype. Is that also a problem? Should I be defining it elsewhere?
I am SO SORRY for the long post, but I have been working on the for 10 hours and I'm about to throw my computer of a cliff.
THANK YOU FOR YOUR HELP STACK OVERFLOW!
This is an in-depth explanation of the details. It might be a bit too much, but if you keep reading, you may get a much deeper understanding of the language than if you just learn to write code that your compiler is ok with.
You are using your struct before you have declared it. Keep in mind that an #include is just a fancy way of telling your compiler: "Please, paste the contents of this .h file at this spot." The result of this pasting must read like valid code to the compiler.
It is true that the compiler's error message looks a bit weird. It certainly does not say "You used struct _data before you declared it". The reason for this is, that structs are implicitly declared at their first use. So, if you declare a variable with struct foo* bar; and the compiler has never seen a struct foo before, it will immediately consider struct foo as being declared, and a pointer variable to this struct foo of unknown size and shape will be defined. Likewise, when your compiler sees the function declaration
void foo(struct bar *baz);
it sees that it doesn't know a struct bar and implicitly declares one. Because this struct declaration happens inside a function declaration, the resulting type is declared local to the declaration at hand. As such, it is impossible for calling code to pass an argument of the correct type into this function, or even to implement the function in a separate statement. Such a function declaration is always useless. This is what the warning text "its scope is only this definition or declaration, which is probably not what you want" means: The compiler writers knew that such a declaration is bullshit, but it's legal C as far as the standard is concerned, so they compile it, but warn about it.
Ok, let's get to the actual error message. As the compiler tells you, the struct _data was only declared for the function declaration at hand. When your compiler later sees the function implementation, it stumbles across the undeclared struct _data a second time. Again, it implicitly declares a local struct type which is distinct from the previously implicitly declared type. Because those two implicitly declared types are distinct, so are the signatures of the declared functions. However, C mandates that a function can only have one signature, so the compiler produces the error "conflicting types for ‘FREE’".
You can try this out with this simple code:
void foo(struct bar* baz); //warning: local declaration of `struct bar`
void foo(struct bar* baz); //repeated warning + conflicting types error
So, how to fix this?
Simple. Declare your struct before you use it. That way you avoid its implicit declaration. The following code compiles fine:
struct bar; //global declaration of `struct bar`
void foo(struct bar* baz); //`struct bar` is known and the global declaration is used
void foo(struct bar* baz); //same as above, because this uses the same global declaration of `struct bar`, this redeclaration of `foo()` is ok
The declaration of the struct _data belongs into the header file that declares the functions which use struct _data as arguments.
Idiomatic declarations
Usually, types are declared with a typedef. This allows the code to omit the struct keyword when declaring variables. This takes one of two idiomatic forms:
To have a type with public members (pure data, no object in the OO sense), put the struct definition into the header:
typedef struct foo //`struct foo` is declared implicitly here
{ //it is also defined (= inner details are given) right here
int bar; //its member variables are defined
} baz; //this concludes the typedef, giving `struct foo` a second name
//`struct foo` and `baz` are now equivalent.
Usually, the two names will be the same or very similar, so the cleaned definition looks like this:
typedef struct foo {
int bar;
} foo;
//declarations of the functions that use `struct foo`
...
If the type is an object that should keep its data members to itself, the declaration and definitions are split like this:
Inside foo.h:
typedef struct foo foo; //declare that `struct foo` == `foo` exists, but don't give details
//declare the functions working on a `foo`
void foo_bim(foo* me);
void foo_bam(foo* me, ...);
...
Inside foo.c:
#include "foo.h" //so that the compiler may check that the function declarations in the header agree with the implementations in this file
struct foo { //define the size and shape of `struct foo` == `foo`
int bar;
};
//now only this file knows how a `struct foo` actually looks like
//implement the member functions of `foo`
void foo_bim(foo* me) {
...
}
void foo_bam(foo* me, ...) {
...
}
Note that the typedef ... non-struct-name; is purely optional in both cases, and there are quite a few programmers who want to see the struct keyword wherever a struct is used (like a certain Mr. Torvalds). These programmers simply leave off the typedef ... non-struct-name; part, otherwise they use the idioms above in the same way. I have described the full-featured version here, to ensure that you'll not be surprised when you first see the typedef construct.
I'm not sure what you did. But to step back: keep clear in your mind the difference between declarations and definitions. A declaration shows a variable or function signature, but does not create any variables of that type or implement that function. A definition declares a new variable (of some type) or implements a function. A declaration of a type just states that it exists (basically). A definition of a type shows its structure and members.
So, a definition of your type would be:
struct _data {
char* name;
long number;
};
And a declaration of a function would be:
void FREE(struct _data *BlackBook, int size);
and a definition of a function would be:
void FREE(struct _data *BlackBook, int size) {
int i;
for (i=0;i<size;i++){
free(BlackBook[i].name);
}
free(BlackBook);
}
So here're the rules:
Only #include header files in other files, never #include source files.
If a type is needed in more than one file, put its definition into a header file and #include that header file in all source files that use the type.
If a function is used in more than one file, put the declaration of that function into a header file and #include that header file in all the source files that use the function, including the source file containing the definition of the function.
If you follow these rules you'll never run into duplicate definitions at link time: you can't have duplicate definitions if you link each source file only one time and no included file contains a definition.
Type declarations can be useful, and breaking some of these rules can be useful, but for the work you're doing that's probably not worth worrying about.
Try to put header of struct declaration at top of files which uses it and be sure you’ve imported the file which contains struct declaration.

How to use struct declare

I want to hide the struct define, so I define struct in the source file, like this :
//a.c
#include "a.h"
struct a_s
{
int a;
int b;
};
int func(a_t *a)
{
printf("%d\n", a->a);
return 0;
}
and I declare the struct in the header file, like this:
//a.h
#ifndef TEST
#define TEST
#include <stdio.h>
#include <stddef.h>
typedef struct a_s a_t;
#endif
Then I use the struct a_t int main.c file, like this:
#include "stddef.h"
#include "a.h"
int main()
{
a_t a;
a.a =2;
func(&a);
return 0;
}
But when I compile the main.c by gcc -c main.c, it failed by
main.c: In function ‘main’:
main.c:7:15: error: storage size of ‘a’ isn’t known
struct a_s a;
Why is this failing?
if you want to hide the struct define, The user can only define the pointer of the type, and you must implement a api that create the struct instance(by malloc) and a api that release the struct instance(by free)
If you instantiate an object A a, the linker searches for the definition of A in order for the compiler to know how much memory it needs to allocate. It searches a.h and finds a typedef but no declaration, and so the error is saying that it doesn't know A's size.
If the purpose of the program is to hide the declarations (and definitions) from the users, you will need to use A *a, as this says to the compiler "there is a type A, and memory for it will be stored beginning at this memory location" and so doesn't need any information about the size or layout of the data until runtime where memory should be dynamically allocated and freed.
This approach allows the developers to expose an interface to users, without the users knowing any specifics on how data is structured and allowing the software to be updated and data structures modified all while keeping the outward facing headers the same (and keeping tests passing).
You can't create an instance of a struct that hasn't been defined because the compiler doesn't know how much space to allocate for it.
You can't access the members of struct that hasn't been defined because the compiler doesn't know their type.
However, you can use a pointer to a struct that hasn't been defined. This allows one to do something as follows:
foo.h:
typedef struct Foo Foo
Foo* Foo_new(int a, int b);
void Foo_destroy(Foo* this);
void Foo_set_a(Foo* this, int a);
void Foo_set_b(Foo* this, int b);
int Foo_get_a(Foo* this);
int Foo_get_b(Foo* this);
// ...
foo.c:
#include "a.h"
struct Foo {
int a;
int b;
};
Foo* Foo_new(int a, int b) {
Foo* this = malloc(sizeof(Foo));
this->a = a;
this->b = b;
return this;
}
void Foo_destroy(Foo* this) { free(this); }
void Foo_set_a(Foo* this, int a) { this->a = a; }
void Foo_set_b(Foo* this, int b) { this->b = b; }
int Foo_get_a(Foo* this) { return this->a; }
int Foo_get_b(Foo* this) { return this->b; }
// ...
main.c
#include <stdio.h>
#include "foo.h"
int main(void) {
Foo* foo = Foo_new(3, 4);
Foo_set_a(foo, 5);
printf("%d %d\n",
Foo_get_a(foo),
Foo_get_b(foo),
);
Foo_destroy(foo);
return 0;
}
You could even include the pointer in the typedef if you wanted a truly opaque type. Normally, that would be a bad practice, but it makes a certain amount in sense in this particular situation. See this for more on this concept.

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; };.

Declaration is incompatible

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.

Resources