I have a simple header file with the following code:
#include < stdio.h >
#include < pthread.h >
void init(struct prodcons * b);
void put(struct prodcons * b, int data);
int get(struct prodcons * b);
void * producer(void * data);
void * consumer(void * data);
when I compile the terminal give this four warnings:
producer_consumer.h:4:18: aviso: ‘struct prodcons’ declared inside parameter list [enabled by default]
producer_consumer.h:4:18: aviso: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
producer_consumer.h:6:17: aviso: ‘struct prodcons’ declared inside parameter list [enabled by default]
producer_consumer.h:8:16: aviso: ‘struct prodcons’ declared inside parameter list [enabled by default]
You need to declare struct prodcons somewhere. Right now there's no declaration for it, so the compiler is inferring it.
Presumably you have a declaration for this in another file -- if it's in another header, add an #include directive for it to the top of this .h file, before all the functions that use it.
The compiler complains about the missing declaration of "struct prodcons". You have to include a header file that actually gives a declaration of that struct, or you have to insert a forward declaration of that struct, like just writing:
struct prodcons;
struct prodcons has not been defined anywhere. You need to define it before those prototypes, or #include a header file that defines it.
Since the parameter list is the first time the compiler has seen struct prodcons, it assumes that you are declaring it there (which makes no sense).
Related
I have two files, main.c and other.h. I declare a few global variables in main.c, and most of them are fine. I can say extern whatever in other.h and access those variables. However, I defined a struct like this (in main.c):
struct LSA {
int myID;
int seqNum;
int neighborID[256];
int costs[256];
} local_LSA[256];
And when I try to access it in other.h like this
extern struct LSA local_LSA[256];
I get this error message
other.h:27:19: error: array type has incomplete element type ‘struct LSA’
extern struct LSA local_LSA[256];
I've been playing around with for a while, but... I appreciate any help anyone is able to provide!
The structure type needs to be defined before any instances of it can be created.
You need to move the struct definition into other.h before local_LSA is defined.
The header file isn't aware of the struct definition of struct LSA. What you should do instead is to declare the struct in some "lsa.h" then define and allocate the variables of that type in some .c file.
Please note that the design you suggest is spaghetti programming. There should never be a reason for another file to extern access some variable in main.c, which is the top level of your program - or otherwise your program design is flawed. Use setter/getter functions instead of spaghetti.
According to the C Standard (6.7.6.2 Array declarators)
...The element type shall not be an incomplete or function type.
In this declaration of an array within the file other.h
extern struct LSA local_LSA[256];
the element type struct LSA is incomplete type because the structure definition at this point is unknown.
So the compiler issues the corresponding error message.
other.h:27:19: error: array type has incomplete element type ‘struct LSA’
extern struct LSA local_LSA[256];
What you need is to place the structure definition in the header before the array declaration.
You could write for example in the header file other.h
struct LSA {
int myID;
int seqNum;
int neighborID[256];
int costs[256];
};
extern struct LSA local_LSA[256];
Pay attention to that this record
extern struct LSA local_LSA[256];
is a declaration of an array not a definition.
Then in main.c you could place one more declaration of the array like
struct LSA local_LSA[256];
in this case the declaration of the array will generate the so-called tentative definition of the array.
I am trying to pass an entire array into a my function, but I am getting currently getting the error:
test.c: In function 'main':
test.c:4:18: error: expected expression before ']' token
method(myArray[]);
^
test.c: At top level:
test.c:8:6: warning: conflicting types for 'method' [enabled by default]
void method(int arr[]){
^
test.c:4:3: note: previous implicit declaration of 'method' was here
method(myArray[]);
^
test.c: In function 'method':
test.c:9:3: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]
printf("DATA: %d",arr[2]);
^
This is my code (a simplified version of what I'm trying to do that throws up the same error:
int main(){
int myArray[3];
myArray[2]=12;
method(myArray[]);
}
void method(int arr[]){
printf("DATA: %d",arr[2]);
}
When passing an array to a function, you don't need the [] after it. Just using the name of the array is sufficient.
Also, you need to either define or declare your functions before they're used, and you need to #include <stdio.h> so the compiler knows the definition of printf.
#include <stdio.h>
void method(int arr[]);
int main(){
int myArray[3];
myArray[2]=12;
method(myArray);
}
void method(int arr[]){
printf("DATA: %d",arr[2]);
}
More than one point to be mentioned here,
Firstly, include the required header files which contains the function signature of the library functions you're going to use.
Secondly, either forward declare the function prototype or define the function before usage. Be aware, the ancient implicit declaration rule has been officially dropped from the C standards.
Thirdly, change
method(myArray[]);
to
method(myArray);
as the array name itself gives you the base address of the array, which is basically what you need to pass.
#include <stdio.h>
#include <stdlib.h>
void f(struct emp);
struct emp{
char name[20];
int age;
};
int main(){
struct emp e = {"nikunj", 23} ;
f(e);
return 0;
}
void f(struct emp e){
printf("%s %d\n", e.name, e.age);
}
Running the above code gives the following errors
nikunjbanka#ubuntu:~$ gcc hello2.c -o main.out
hello2.c:3:15: warning: ‘struct emp’ declared inside parameter list [enabled by default]
hello2.c:3:15: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
hello2.c: In function ‘main’:
hello2.c:10:2: error: type of formal parameter 1 is incomplete
hello2.c: At top level:
hello2.c:14:6: error: conflicting types for ‘f’
hello2.c:3:6: note: previous declaration of ‘f’ was here
But the book test your C skills says that the order of prototype declaration and structure declaration in the program does not matter. I want to ask whether the order matters or not?
Yes the order absolutely does matter.
Re-order your code such that the definition of struct emp appears before the function prototype for f.
#include <stdio.h>
#include <stdlib.h>
struct emp{
char name[20];
int age;
};
void f(struct emp);
...
gcc is actually trying to tell you that you did things in the wrong order, however the compiler messages are a little bit confusing if this is your first time reading through them.
These two warnings:
hello2.c:3:15: warning: ‘struct emp’ declared inside parameter list [enabled by default]
hello2.c:3:15: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
indicate that the type of 'struct emp' was not known at the time gcc compiled line 3 of your file. The compiler will typically try to infer a default type & size for the unknown struct emp and almost always guesses incorrectly because it has no idea how you will eventually declare struct emp.
This error:
hello2.c:10:2: error: type of formal parameter 1 is incomplete
indicates that you are trying to call function 'f' with an actual parameter type that is different than the formal parameter type that gcc (incorrectly) inferred when it compiled line 3 of the file.
This error and associated note:
hello2.c:14:6: error: conflicting types for ‘f’
hello2.c:3:6: note: previous declaration of ‘f’ was here
indicates that the formal parameter type on line 14 (which is now known to be the type struct emp you declared on lines 4 through 7) did not match the formal parameter type that gcc (again incorrectly) inferred on line 3.
Bottom line: define all of your types before the prototypes that refer to them, and you should be fine.
You may also find your code is more readable if you use
typedef struct {
char name[20];
int age;
} emp_t;
And then you can use emp_t rather than struct emp throughout the subsequent code.
There's another option - this change will fix it too:
#include <stdio.h>
#include <stdlib.h>
struct emp; /* <--- add this line */
void f(struct emp); /* <-- now this refers to that */
struct emp{ /* <-- and this defines the same thing */
char name[20]; /* and you didn't need to move things around. */
int age;
};
In a complex project it's not always easy to resolve all the ordering issues, this can be helpful.
Note that when f is actually f(struct emp*) --not f(struct emp)- then you may be able to define f() without including a definition of the struct layout.
This is because the compiler can work with pointers to structs that are named, but not defined - provided you only do certain things to them (store them, return them, pass them to other functions; compare them to NULL, or to other pointers to the same thing... cast them to other pointer types...) - but you can't do pointer arithmetic, or access members (obviously) or ask for sizeof(*p) if p is a pointer to an unspecified struct. The compiler will let you know :-)
I have a file global.h which is included across many files in the project and contain general headers. The relevant contents of file is given below:
#define DEBUG
#ifdef DEBUG
extern int debug_level;
#endif
It has been included in main.c and there is a warning corresponding to the following line in main.c
#ifdef DEBUG
debug_level = 6; //compiler generates warning corresponding to this line.
#endif
The warning message issued by compiler is:
src/main.c:14:1: warning: data definition has no type or storage class [enabled by default]
src/main.c:14:1: warning: type defaults to ‘int’ in declaration of ‘debug_level’ [enabled by default]
I do not understand what is that I am doing wrong. Surprisingly the program works fine because I think that compiler assumes that the number is an int(by default).
You should define as int as
#ifdef DEBUG
int debug_level = 6; //define as int
#endif
With your code, its implicitly defined as int, hence the warning.
And extern int debug_level; is not definition but a declaration.
You can't just set the variable in global scope, you actually have make a definition that matches the declaration in the header file:
#ifdef DEBUG
int debug_level = 6;
#endif
Declare the variable debug_level as external if it is already declared some where else. Then the compiler will look for the declaration on other places also.
#ifdef DEBUG
external int debug_level = 6;
#endif
I'm having trouble with a C concept. I'll be up-front, it's part of an assignment for my "Special Topics in Programming: Linux and C" class. I'm trying to make functions to write specific strings into a file (it's an accounting program, and the functions write page headers and footers), and I'm getting an error.
My code:
#include <stdio.h>
void writeToFile(FILE dataOut, char content[])
{
fprintf(dataOut, content);
}
void main()
{
FILE *dataOut;
dataOut = fopen("testWrite.txt", "w");
writeToFile(dataOut, "Leave no bars un-foo'd.");
}
The error message I get when I try to compile:
testWrite.c: In function ‘writeToFile’:
testWrite.c:5:2: error: incompatible type for argument 1 of ‘fprintf’
In file included from testWrite.c:1:0:
/usr/include/stdio.h:357:12: note: expected ‘struct FILE * __restrict__’ but
argument is of type ‘FILE’
testWrite.c: In function ‘main’:
testWrite.c:12:2: error: incompatible type for argument 1 of ‘writeToFile’
testWrite.c:3:6: note: expected ‘FILE’ but argument is of type ‘struct FILE *’
I'm not sure how to fix this. I've tried manipulating pointers a bit, but it didn't change the error message. This code is an isolated example of what I want my code to do; if you would like to see the actual code, let me know. This just seemed like a clearer way to express what I was dealing with.
Change your function accept a pointer instead of the struct itself:
void writeToFile(FILE * dataOut, char content[])
The problem here is that you are attempting to pass a pointer to a parameter that is expecting a non-pointer value. The first parameter to writeToFile is FILE but the parameter dataOut is of type FILE*. In order to make this work you need to make them both pointer values
void writeToFile(FILE* dataOut, char content[])