I'm currently working on a c project and to keep my code organized I use include files. One file includes.h has a typedef and I wan't to access this in a different included file util.h/util.c. I included them both in main.c in the following order: includes.h util.h.
main.c:
#include <stdio.h>
#include <stdlib.h>
//similar includes
#include "includes.h"
#include "util.h"
int main()
{
MyStructType somename;
somename.number = 5;
util_foo(somename);
return 0;
}
includes.h:
#pragma once
struct structname
{
int number;
};
typedef struct structname MyStructType;
util.h:
#pragma once
#include "includes.h" //added line (>accepted answer)
int util_foo(MyStructType blabla);
util.c:
#include <stdio.h>
#include "util.h"
int util_foo(MyStructType blabla)
{
printf("%d\n", blabla.number);
return 0;
}
I compile with this command: gcc -o main *.c
But this doesn't compile, do you have any idea why this doesn't work? Or how to fix it without changing my projects' structure completely?
Edit:
It is recommended to replace #pragma once with:
#ifndef STH_SIMILAR_TO_FILENAME
#define STH_SIMILAR_TO_FILENAME
//code
#endif
You need to add
#include "includes.h"
in util.h in order to make your code compile.
This is because you're relying on transitive #include directives to get the MyStructType typedef into util.h from main.c, but you're not doing the same in util.c.
The best solution (for maintainability purposes) is to minimize relying on transitive inclusions: you should include includes.h wherever it's needed (in this case, in util.h).
Related
In a CLion project, I have two C-language source files, "main.c" and "list.c".
The source file "main.c" has this:
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
The source file "list.c" has this:
#include <stdio.h>
int printFoo() {
printf("I want Krabby Patties!\n");
return 0;
}
Now how do I call printFoo() from the main() function? I know I cannot do an include<list.c> in main.c since that will cause a multiple definitions error.
CLion uses CMake for organizing and building project.
CMakeLists.txt contains instructions for building.
Command add_executable(program main.c list.c) creates executable with files main.c and list.c. Add all source files to it. You can add headers, but it isn't necessary.
Header files contain definitions of functions and other things, source files for realization, but you can merge them.
main.c
#include "list.h"
int main() {
printFoo();
return 0;
}
list.h
#pragma once
int printFoo();
list.c
#include "list.h"
#include <stdio.h>
int printFoo(){
return printf("I want Krabby Patties!\n");
}
#pragma once tels compiler to include header file once. If you have more than one include of one file without #pragma once, you'll catch an error.
You can create one header file "list.h"
#ifndef __LIST_H__
#define __LIST_H__
int printFoo();
#endif
Then include it in main.c:
#include <stdio.h>
#include "list.h"
int main() {
printf("Hello, World!\n");
printFoo();
return 0;
}
First of all I am sorry for the title. I really did not know how I could describe my problem in a better way.
When using XCode, I have this problem that "typedefs" and "#defines" only seem to be visible for the file where they are written in.
Let's assume I have three files. main.c, Foo.h, Foo.c
main.c:
#include <stdio.h>
#include <stdlib.h>
typedef int simpleInteger;
#include "Foo.h"
int main(int argc, const char * argv[]) {
simpleInteger I = 22;
printf("%d\n", Foo(I));
return 0;
}
Foo.h:
#ifndef Foo_h
#define Foo_h
simpleInteger Foo(simpleInteger number);
#endif /* Foo_h */
Foo.c:
#include "Foo.h"
int Foo(simpleInteger number)
{
return number*2;
}
When I try to compile this, XCode throws the error "Unknown type name 'simpleInteger'" in Foo.h and Foo.c.
To make this to work I have to include the line "typedef int simpleInteger" in Foo.h which seems not clean to me. However if I compile these files without the use of XCode, it just works perfectly.
How can I tell XCode to not complain about this and make it work like any other compiler would do?
This needs to be in Foo.h, not main.c:
typedef int simpleInteger;
I'm having trouble finding my error. Here is a definition in structures.h
typedef struct book {
bank_account_t **accounts;
transaction_t **transactions;
} book_t;
And here is in functions.c where I include header and try to use the type book_t
#include "structures.h"
void load_book(book_t *book) {
}
But I get this error
functions.c:10:16: error: unknown type name ‘book_t’
void load_book(book_t *book) {
^
Edits with more code below:
In my main file I order my .h files like so
#include "structures.h"
#include "functions.h"
structures.h
#ifndef STRUCTURES_H
# define STRUCTURES_H
typedef struct bank_account {
char *name;
int amount;
} bank_account_t;
typedef struct transaction {
char *name;
int amount;
} transaction_t;
typedef struct book {
bank_account_t **accounts;
transaction_t **transactions;
} book_t;
#endif
function.c
#include <stdio.h>
#include "functions.h"
#include "structures.h"
#include "bank_account.h"
#include "transaction.h"
void load_book(book_t *book) {
}
void init_book() {
}
bank_account.h
#ifndef BANK_ACCOUNT_H
# define BANK_ACCOUNT_H
void init_new_bank();
void deinit_new_bank();
#endif
transaction.h
#ifndef TRANSACTION_H
# define TRANSACTION_H
#endif
I think the problem must be in functions.h (which is not included in the original post).
functions.h
#ifndef FUNCTIONS_H
# define FUNCTIONS_H
/* [MarkU] required: include definition of book_t */
#include "structures.h"
void load_book(book_t *book);
void init_book();
#endif
Without the #include structures.h there is no definition of the boot_t type.
Built and verified with mingw32-gcc 4.7.2. Omitting the #include, I see the error message.
In functions.c change the order of those:
#include "functions.h"
#include "structures.h"
to be
#include "structures.h"
#include "functions.h"
The subtile thing is that the error message origins from functions.c not from functions.h.
Assuming the protoytpe to load_book(book_t *) in functions.h, it needs to know about book_t.
So the optimal solution to this would be to include structures.h into functions.h (as also already pointed out by MarkU's answer).
Lesson learned: Always (and only) include what you need and where you need it. Avoid (subtile) dependencies.
I have those 3 files in my workspace:
1.h
#ifndef SOME_HEADER_FILE_H
#define SOME_HEADER_FILE_H
//code
#endif
1.c
#include <stdio.h>
#include "1.h"
//code
main.c
#include "1.h"
int main(){
printf("hello");
}
but in main.c printf is unidentified, is there a way to make it work while the relevant header is called in 1.c?
how can I link the 1.c and 1.h files?
edit: it's an academic assignment and I'm not allowed to make changes in the main and header.
You have included #include <stdio.h> only in 1.c, not in 1.h or main.c.
Obvious solution is to include it in main.c.
Because of the way the #include macro works (it expands the whole header file that you include at the line where you call the macro), you actually don't need to include stdio.h within main.c as long as stdio.h is included in a header file that main.c includes.
Hopefully this makes it clear:
main.c
#include "test.h"
int main()
{
printf("I can call this function thanks to test.h!\n");
return 0;
}
test.h
#include <stdio.h>
This will work just fine.
But this is not the same as being able to use a function that a .c file has access to based on its own #include definition just because you cross-compiled them. In that case the other.c file that calls #include <stdio.h> will get printf(), but main.c does not.
In this setup,
main.c
int main()
{
printf("I don't have any way to call this...\n");
return 0;
}
test.c
#include <stdio.h>
You will not have any way for main to know what printf() is, even if you cross-compile the two. test.c knows what printf() is but not main.
What you want is to have #include <stdio.h> in other.h, and then #include "other.h" in main.c.
But for future reference, this is probably poor practise as it should be immediately apparent what each file's requirements are so that you get a good sense of what its job is.
So here's what I would probably suggest as the best solution:
main.c
#include <stdio.h>
int main()
{
printf("I can call this all on my own.\n");
return 0;
}
I have three files, say A.c , B.c and C.c, all of which #include common.h
In common.h, I include "sys/socket.h" and I protect the common.h by macros:
#ifndef __COMMON_H
#define __COMMON_H
// body of file goes here
#endif
When i compile the code, I get several errors such as below
In file included from /usr/include/sys/socket.h:40,
from tcpperf.h:4,
from wrapunix.c:1:
/usr/include/bits/socket.h:425: error: conflicting types for 'recvmmsg'
/usr/include/bits/socket.h:425: note: previous declaration of 'recvmmsg' was here
In file included from /usr/include/sys/socket.h:40,
from tcpperf.h:4,
from wrapsock.c:1:
As you can see wrapunix.c and wrapsock.c, they both include tcpperf.h, but tcpperf.h is guarded with macros,yet gcc complains that recvmsg was declared multiple times. How do I resolve this issue?
Update:
Here is the header of tcpperf.h, that is causing issues
#ifndef _TCPPERF_H
#define _TCPPERF_H
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include <regex.h>
#include <errno.h>
#include <sched.h>
#include <pthread.h>
#include <argp.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <linux/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/prctl.h>
#include <unistd.h>
#include <sys/wait.h>
#endif
The above error can be reproduced by providing "-combine -fwhole-program" flags to gcc such as
gcc -std=gnu99 -Wall -combine -fwhole-program -I. error.c wrapunix.c wrapsock.c file1.c file2.c -o file2 -lrt
The error is "conflicting types for 'recvmmsg'" rather than just duplicate definition (which would be tolerated if equal). That means your .c source receives two different version of recvmmsg: one by your direct tcpperf.h inclusion and another one by inclusion it via sys/socket.h. I believe you have another version of tcpperf.h elsewhere in inclusion path with different (perhaps older version) recvmmsg.
The problem is almost certainly related to -combine. This is a bit of a guess, but in looking at the definition of recvmmsg:
extern int recvmmsg (int __fd, struct mmsghdr *__vmessages,
unsigned int __vlen, int __flags,
__const struct timespec *__tmo);
note that it takes a struct mmsghdr as an argument. However, while this prototype is unconditional, struct mmsghdr is only defined if __USE_GNU is set:
#ifdef __USE_GNU
/* For `recvmmsg'. */
struct mmsghdr
{
struct msghdr msg_hdr; /* Actual message header. */
unsigned int msg_len; /* Number of received bytes for the entry. */
};
#endif
-combine is basically equivalent to concatenating all your files together and then compiling them. Is there any chance that between the text of wrapunix.c and wrapsock.c that GNU_SOURCE is being defined? If that happened, then the first definition of recvmmsg would use a definition of struct mmsghdr that was local to just the prototype, while the second definition would use the real struct. Those two definitions would then be incompatible, which would result in the error message that you got.