Precompiled header via unclude directive - c

I have two headers world.h worldw.h.
world.h
void h_world();
worldw.h
void g_world();
After precompilation with gcc world.h and gcc worldw.h I have world.h.gch and worldw.h.gch. Futher I'm adding this precompiled headers to main.c:
#include "world.h.gch"
#include "worldw.h.gch"
....
But when I'm compiling this I have more than thousand errors. I'm expected that it's ok, because precompiled header is just reduce a compile time.

Instead of
#include "world.h.gch"
#include "worldw.h.gch"
you need
#include "allworld.h"
And in allworld.h put
#include "world.h"
#include "worldw.h"
Then precompile allworld.h ... if a .h.gch file exists, the compiler will use it; if not, it will use the .h file. You can see what is being used by compiling your source with the -H flag.
There are a number of restrictions for using a precompiled header; see http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html

Related

Assimp multiple definition error in material.h when linking across multiple compilation units

I'm following the example provided at https://assimp.sourceforge.net/lib_html/usage.html to import a simple model using the assimp library. The first three lines in the example are the required include statements:
#include <assimp/cimport.h> // Plain-C interface
#include <assimp/scene.h> // Output data structure
#include <assimp/postprocess.h> // Post processing flags
Of these, scene.h seems to be problematic. If you include it AND link against a compilation unit that also includes it, it gives multiple definition errors for aiGetMaterialFloat and aiGetMaterialInteger. A stripped down example is given below:
main.c:
#include <assimp/cimport.h> // Plain-C interface
#include <assimp/scene.h> // Output data structure
#include <assimp/postprocess.h> // Post processing flags
#include "model.h"
//...
model.h:
#include <assimp/cimport.h> // Plain-C interface
#include <assimp/scene.h> // Output data structure
#include <assimp/postprocess.h> // Post processing flags
//...
model.c
#include "model.h"
makefile:
main: main.c model
gcc main.c model.o
model: model.c model.h
gcc -c model.c
I'm using MinGW to compile these.
Now this DOES seem to compile if:
main.c does not include model.h, OR
the include statements are removed from model.h, OR
model.o is not linked when compiling main.c, OR
the import for scene.h is removed from one or both files
It will also compile just fine if the #includes are all moved to main.c and the model compilation unit is removed entirely.
Note that if one of the above conditions are met, this compiles just fine without a DLL or static library linked. The problem seems to be exclusively from including the header files.
I've done a lot of research and the only thing I could find is that it might be the inline specifier on these functions that was causing the issue. However, after removing the inline specifiers from the function definitions in the library header file, I'm still getting the same errors. I've been trying to solve this issue for hours and nothing seems to be working. Any ideas?

Do I need to include files that my included files depend on?

I have a C program named coderTest.c in a directory. In a sub-directory, src, I have several files, one.c, two.c, three.c, and their associated header files one.h, two.h, three.h.
I want to use functions from one.c and two.c in coderTest.c. Both one.c and two.c use functions from three.c. Do I need to include three.c in coderTest.c, or will it take care of it's dependency on it's own?
I am using #include "src/one.h" for one and two.
Do I need to include three.c in coderTest.c, or will it take care of
it's dependency on it's own?
You don't need to include "src/three.h" in coderTest.c, but this does not mean, that compiler does handle dependency automagically. This header needs to be included in one.c, two.c and three.c. The last one is to confirm that header's declarations and definitions match with each other properly.
As a result, you project might look as:
coderTest.c:
#include "src/one.h"
#include "src/two.h"
// ...
src/one.c:
#include "one.h"
#include "three.h"
// ...
src/two.c:
#include "two.h"
#include "three.h"
// ...
src/three.c:
#include "three.h"
// ...
To prevent multiple includes of same header, use header guards for each header file individually.
In coderTest.c, include the following:
#include "src/two.h
#include "src/one.h
In one.c, include:
#include "src/three.h
In two.c, include:
#include "src/three.h
Do I need to include three.c in coderTest.c, or will it take care of it's dependency on it's own?
No you don't need to include three.c in coderTest.c, because one.c and two.c abstract it away.
As long as two.c and one.c properly #include "three.h" then the compiler will be able to chain the dependencies together without a problem. If you wanted to run something from three.c in coderTest.c it would want you to #include it in there as well.
Do your files have the preprocessor directives #IFNDEF, #DEFINE, and #ENDIFin place to prevent duplicate importing?
You can do what you want several ways as long as visibility to necessary prototypes is provided. In addition to where best to include header files, consider using wrappers to guarantee your header is used only once:
#ifndef _SOMEFILE_H_
#define _SOMEFILE_H_
the entire file
#endif /* SOMEFILE_H__SEEN */
Also consider readability. For example given: coderTest.c, one.c/.h, two.c/.h, three.c/.h are as you described:
1) You should include three.h in both one.c and two.c.
2) For coderTest.c, #include headers of all supporting headers either in the file itself, or perhaps in a collector header: conderTest.h:
coderTest.h:
#include "./src/one.h"
#include "./src/two.h"
#include "./src/three.h"
coderTest.c
#include "coderTest.h"

Multiple definition of in C

I have a project written in C consisting of FIFO.h, FIFO.c, task.h, task.c and main.c (it's a basic queue).
When I compile my main.c using gcc under Windows it compiles and works just fine. However when I try to compile the exact same code in Eclipse, I get the following error for every function:
One example is:
In function `queue_new':
FIFO\Debug/../src/QueueFIFO.c:20: multiple definition of `queue_new'
src\main.o:FIFO\Debug/../src/QueueFIFO.c:20: first defined here
src\FIFO.o:
I honestly have no idea what additional information you guys could use so just tell me what to do.
main.c includes:
#include "FIFO.h"
#include "FIFO.c"
#include "task.h"
QueueFIFO.c:
#include "task.h"
FIFO.c:
#include "task.h"
#include "QueueFIFO.c"
task.c:
#include "task.h"
You are getting multiple definition errors because you are including your .c files in your .c files. It's the linker's job to make sure they come together. Good practice is to only include .h files in your .c files, and make sure the .h files don't include function definitions (only function prototypes).
By #includeing your .c files, you are defining the functions at least twice: once when FIFO.c is compiled, and again when main.c (which #includes FIFO.c, copying it verbatim into the text before compilation) is compiled. When it comes to link time, the linker sees e.g. queue_new() defined in both FIFO.o and main.o and barfs on the multiple definition of all the functions in FIFO.c.
In addition, as others mentioned, make sure you "guard" your header files to make sure they don't create circular #include dependencies. You can do that with #ifndef and #define as follows:
/* foo.h */
#ifndef FOO_H
#define FOO_H
#include "bar.h"
#include "baz.h"
/* header file contents go here */
#endif /* FOO_H */
This has the effect of only executing the contents of the file once, since FOO_H will be defined if it is included a second time, and the entirety of the file will be skipped over.

Do I need to include system header file in the source if another header file already includes it?

For example, in the header file example.h, I wrote:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
And in the source file example.c, I wrote:
#include "example.h`
Do I still need to explicitly wrote these lines if I need functions of these libararies?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
Thanks!
No.
Keep in mind that includes works like some kind of text substitution, as it's done by the preprocessor.
When you write, on some file:
#include "someheader.h"
It's just like that line will be replaced with the actual content of the header file.
No, you don't.
Include will, as it's named, include the whole content of your header file in your .c file.
If you are using linux, try cpp example.c or gcc -E example.c to see what #include does. You will run the c-preprocessor on your file, which is the program that interpret all # started instructions before the copilation

C - adding base64 methods to my file

I found these libraries: http://svn.opendnssec.org/trunk/OpenDNSSEC/common/ for encoding in c. I want used them but I am not sure how can I add them.
If I add #include "b64_ntop.c" I have problem with #include <config.h> in b64_ntop.c (no such file or directory). How can I add these modules?
My makefile:
CC=gcc
CFLAGS=-std=gnu99 -Wall -pedantic
all: rdtclient
rdtclient: b64_ntop.o rdtclient.o
$(CC) $(CFLAGS) b64_ntop.o rdtclient.o -o rdtclient
Thanks for help
For that particular file, you can remove every header except <stdlib.h> (needed for abort()), but you would add <stdint.h> to get uint8_t.
#include <config.h> // Remove
#include <sys/types.h> // Remove
#include <sys/param.h> // Remove
#include <sys/socket.h> // Remove
#include <netinet/in.h> // Remove
#include <arpa/inet.h> // Remove
#include <ctype.h> // Remove
#include <stdio.h> // Remove
#include <stdlib.h> // Keep
#include <string.h> // Remove
#include <stdint.h> // Add
There's no need for the others that I can see, and GCC agrees with me when I tested it.
I'm not sure which header introduced uint8_t; most likely, it was <sys/types.h>, but the C standard says <stdint.h> does that (or <inttypes.h> does it).
You should also have a header which declares the function, and that header should be included in this file to ensure that the function declaration and definition agree, and the header should be included in each source file that uses the function. Obviously, that's one more #include line in the source file.
In general, if a file uses <config.h> (or, more usually, "config.h"), then you need to use the configuration tool (usually autoconf or automake) or the configure script that is generated by the tools to create the config.h header. In this file, there was no conditional code affected by the configuration header, so it could be removed.
Once you've cleaned up the header list, you can treat the file as you would any other source file in your project. It would be best to compile it as a separate object file (no special options needed) which is added to the build. That's what your makefile seems to be doing perfectly well. Occasionally, it is sensible or necessary to include a source file (as opposed to header file) in another source file. The number of times that is sensible is strictly limited, though.
You should not #include a C file. Instead #include compat.h and specify the path to the header file in the CFLAGS using the -I option thus:
CFLAGS=-std=gnu99 -Wall -pedantic -Ipath/to/header

Resources