My compilation order is :
core1.c
top.c
core1.c contents :
#include "header1.h"
#include "header2.h"
void function1() {
---- }
void function2() {
---- }
header1.c contents function declarations, enums, includes :
#include comdef.h
void function1();
void function2();
top.c contents :
#include "header1.h"
#include "header2.h"
void main() {
function1();
function2();
}
I will add more headers and more core C files into my project. Each core.c file needs the same header files. How to get this all working, without the need to put #include header1/2.h in each core1.c, core2.c etc, and include these headers only in main.c ?
You can use a global header including all files
/* glob.h */
#ifndef GLOB_H
#define GLOB_H
#include "header1.h"
#include "header2.h"
#endif /* GLOB_H */
and in your main file
#include "glob.h"
Even if this is considered bad style, there are several projects using this approach, i.e. gtk
Use one header for each source file:
core1.h:
#ifndef _CORE1
#define _CORE1
#include comdef.h
void function1();
void function2();
#endif
core1.c:
#include "core1.h"
void function1() {
---- }
void function2() {
---- }
top.c:
#include "core1.h"
void main() {
function1();
function2();
}
Related
I have the following source named lcd.c.
#include <stdio.h>
#include "lcd.h"
void print_mode(void)
{
printf("%d\n",LCD_MODE);
}
The header lcd.h contains the definition for LCD_MODE as follows.
#ifndef LCD_H
#define LCD_H
#include "util.h"
#ifndef LCD_MODE
#define LCD_MODE LCD_MODE_8BIT
#endif
void print_mode(void);
#endif /* LCD_H */
The file util.h contains
#ifndef UTIL_H
#define UTIL_H
#define LCD_MODE_8BIT 1
#define LCD_MODE_4BIT 0
#endif /* UTIL_H */
lcd.c will be compiled separately as part of some library. I want to use it with an application main.c as follows.
#include "util.h"
#define LCD_MODE LCD_MODE_4BIT
#include "lcd.h"
int main(void)
{
print_mode();
return 0;
}
The desired outcome is to print 0 as per the definition of LCD_MODE_4BIT in main.c. However, 1 is printed because the header file sees that LCD_MODE is not defined during the preprocessing for lcd.c. How should I go about passing the LCD_MODE option to print_mode() through the main application?
if you cannot recompile lcd.c you cannot use a macro in another source file, because lcd.o already has the value hardcoded.
You could create a static variable (which defaults to LCD_MODE) that you can change using a setter:
#include <stdio.h>
#include "lcd.h"
static int the_mode = LCD_MODE;
void print_mode(void)
{
printf("%d\n",the_mode);
}
void set_mode(int new_mode)
{
the_mode = new_mode;
}
lcd.h should contain the prototype for the new configuration function BTW:
void set_mode(int new_mode);
then in your main, you can:
set_mode(LCD_MODE);
(or drop that LCD_MODE macro everywhere because it solves nothing and adds to the confusion)
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'm getting started with C programming. I currently have a large file that contains a lot of functions. I would like to move these functions to a separate file so that the code is easier to read. However, I can't seem to figure out how to properly include/compile and can't find an example in any online tutorials that I've found. Here's a simplified example:
#include <stdlib.h>
#include <stdio.h>
void func1(void) {
printf("Function 1!\n");
}
void func2(void) {
printf("Function 2!\n");
}
int main(void) {
func1();
func2();
return 0;
}
How do you move C functions into a separate file? FYI: I'm using gcc.
Update: These answers are very helpful, thank you. Now it seems that my simplified example is not good enough because I realized the reason my program failed to compile is because I'm using a global variable in my functions.
#include <stdlib.h>
#include <stdio.h>
int counter = 0;
void func1(void) {
printf("Function 1!\n");
counter++;
}
int main(void) {
func1();
return 0;
}
Moving these functions to an external file doesn't work because they need to reference this global variable:
#include <stdlib.h>
#include <stdio.h>
#include "functions.c"
int counter = 0;
int main(void) {
func1();
counter = 100;
return 0;
}
How can I get around this issue?
Okay. Here we go.
Your main.c file
#include <stdlib.h>
#include <stdio.h>
#include "functions.h"
int main(void) {
func1();
func2();
return 0;
}
Your functions.h file
void func1(void);
void func2(void);
Your functions.c file
#include "functions.h"
void func1(void) {
printf("Function 1!\n");
}
void func2(void) {
printf("Function 2!\n");
}
Compile it with:
gcc -o main.exe main.c functions.c
The most common way is to place your function prototypes in a header file and your function implementations in a source file. For example:
func1.h
#ifndef MY_FUNC1_H
#define MY_FUNC1_H
#include <stdio.h>
// declares a variable
extern int var1;
// declares a function
void func1(void);
#endif
func1.c
#include "func1.h"
// defines a variable
int var1 = 512;
// defines a function
void func1(void) {
printf("Function 1!\n");
}
func2.h:
#ifndef MY_FUNC2_H
#define MY_FUNC2_H
#include <stdio.h>
void func2(void);
#endif
func2.c:
#include "func1.h" // included in order to use var1
#include "func2.h"
void func2(void) {
printf("Function 2 with var1 == %i\n", var1);
}
main.c:
#include <stdio.h>
#include "func1.h"
#include "func2.h"
int main(void) {
var1 += 512;
func1();
func2();
return 0;
}
You would then compile using the following:
gcc -c -o func1.o func1.c
gcc -c -o func2.o func2.c
gcc -c -o main.o main.c
gcc -o myprog main.o func1.o func2.o
./myprog
I only placed one function in each source/header pair for illustration. You could create just one header which includes the prototypes for all of the source files, or you could create multiple header files for each source file. The key is that any source file which will call the function, needs to include a header file which includes the function's prototype.
As a general rule, you only want a header file included once, this is the purpose of the #ifndef #define #endif macros in the header files.
First you have to learn the difference between a declaration and definition. A declaration tells the compiler that something, like a function, exists. A definition is, for the case of functions, the actual function implementation.
So what you do is move the definition to another file, but add a declaration in the file where the function is to be called. You then build both files together, and the compiler and linker will take care of the rest.
You can do something like this.
/* func1.c */
void func1(void) {
printf("Function 1!\n");
}
/* func2.c */
void func2(void) {
printf("Function 2!\n");
}
/* main.c */
#include "func1.c"
#include "func2.c"
int main ( void )
{
func1();
func2();
return 0;
}
I have 3 *.c files (file1.c, file2.c and file3.c) and 1 *.h file (file3.h) in a project (Visual Studio).
/*******************************
file3.h
********************************/
#ifndef FILE3_H
#define FILE3_H
int gintVariable = 400;
#endif
/*******************************
file1.c
********************************/
#include "file3.h"
#include <stdio.h>
#include <conio.h>
int modifyGlobalVariable(void);
void printGlobalVariable(void);
int main(void)
{
modifyGlobalVariable();
printGlobalVariable();
printf("Global variable: %d\n", gintVariable++);
getch();
return 0;
}
/*******************************
file2.c
********************************/
#include "file3.h"
int modifyGlobalVariable(void)
{
return gintVariable++;
}
/*******************************
file3.c
********************************/
#include "file3.h"
#include <stdio.h>
void printGlobalVariable(void)
{
printf("Global: %d\n", gintVariable++);
}
When I build the solution in VS, it is giving error as "_gintVariable already defined in file1.obj".
I did check in the pre-processor output, the gintVariable is included in all the *.c files even though I have included include guards.
What mistake I am doing?
You should use 'extern' while declaring a global variable in header file.
Define it in any one of *.c file.
This should fix the issue.
For more on header files, read
How do I use extern to share variables between source files?
Including guards prevents multiple inclusion (or, more precisely, multiple compilation of the .h file content) in a single translation unit.
It is useful against this problem:
/* glob.h */
#ifndef H_GLOB
#define H_GLOB
struct s { int i; };
#endif
/* f.h */
#ifndef H_F
#define H_F
#include "glob.h"
struct s f(void);
#endif
/* g.h */
#ifndef H_G
#define H_G
#include "glob.h"
struct s g(void);
#endif
/* c.c */
#include "f.h" /* includes "glob.h" */
#include "g.h" /* includes "glob.h" */
void c(void) {
struct s s1 = f();
struct s s2 = g();
}
The inclusions is like a diamond:
glob.h
/ \
f.h g.h
\ /
c.c
display.h
#ifndef PRO_DISPLAY_H
#define PRO_DISPLAY_H
/** Initializes the display **/
int pro_display_init(void);
#endif /* PRO_DISPLAY_H */
display.c
#include "main.h"
static int height_ = 300;
static int width_ = 300;
static int bpp_ = 16;
static SDL_Surface* screen_ = NULL;
int pro_display_init(void)
{
screen_ = SDL_SetVideoMode(width_, height_, bpp_, SDL_HWSURFACE|SDL_DOUBLEBUF);
if (!screen_)
{
pro_sdl_error("Video initialization failed.");
return 0;
}
return 1;
}
main.h
#ifndef PRO_MAIN_H
#define PRO_MAIN_H
// standard headers
#include <stdlib.h>
#include <stdlib.h>
// conditional headers
#if defined(WIN32) || defined(_WIN32)
#include <windows.h>
#endif
// our own headers
#include "scripter.h"
#include "ttf_util.h"
#include "events.h"
#include "display.h"
// some macros
#define pro_error(...) fprintf(stderr, __VA_ARGS__)
#define pro_sdl_error(x) fprintf(stderr, "%s. \n=> %s\n", x, SDL_GetError())
#define pro_ttf_error(x) fprintf(stderr, "%s. \n=> %s\n", x, TTF_GetError())
#endif /* PRO_MAIN_H */
** main.c**
#include "main.h"
int main(int argc, char* argv[])
{
pro_display_init();
return 0;
}
The Error:
main.c|5|undefined reference to `pro_display_init()'|
Checked the build process. Made sure I was adding "display.c" to gcc's input files. I'm at my wit's end. Why the error?
display.c and main.c are compiled into their own "translation unit". What happens is that when trying to resolve symbols name (i.e. looking for pro_display_init), the C compiler thinks it's compiling a standalone .c unit. The proper way to go is to compile them separately and then link them, e.g.
gcc -c display.c # creates display.o
gcc main.c display.o # compiles main.o and then link with display.o
Of course, you'll be creating/reusing a Makefile soon that lets you define rules for all this.
I think, #include "main.h" or #include "display.h" (in main.h) "finds" the wrong include file. Check you include_path variable.