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"
Related
I am trying to link the interrupt of the fpga to FreeRTOS in zedboard. When I write the code:
InterruptController = (XScuGic *)prvGetInterruptControllerInstance();
I get an error from Xilinx SDK said:
undefined reference to `prvGetInterruptControllerInstance'
May I know what is the necessary include header file to use that function? I tried to search online and I have the same header file included:
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "FreeRTOSConfig.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
#include "semphr.h"
/* Xilinx includes. */
#include "xil_printf.h"
#include "xparameters.h"
#include <xil_io.h>
#include "xscugic.h"
#include <stdio.h>
Thank you!
1- Your IDE may help you find the header file : right click on the function name, then click on go to the definition, once you get the header file eg file.h you should include it.
2-Your # includeassume that the header files freeRTOS.h... are in the same folder but possibly they are in other folders,
I said that because freeRTOSConfig.his a configuration file that should not be in the same folder as the kernel include filestask.h,...,(at least in the demo project) so make sure that you use the good local /global path to your headers
3- The order of include is not good i guess, the best approach is to go from global to local, stdio.h for example should be at the top of the includes
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.
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
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
I work on AS/400 which is sometimes non-POSIX. We also need to compile our code on UNIX. We have an issue with something as simple as #include.
On AS/400, we need to write: #include "*LIBL/H/MYLIB"
On UNIX, we need to write #include "MYLIB.H"
At the moment we have this (ugly) block at the top of each C/C++ file:
#ifndef IS_AS400
#include "*LIBL/H/MYLIB"
/* others here */
#else
#include "MYLIB.H"
/* others here */
#endif
We would like a unified macro. Is this possible? I don't know how to write it.
Ideally, the resulting syntax would be: SAFE_INCLUDE("MYLIB") that would expand correctly on each platform.
Please advise.
You can simply #include some separate header in every of your source files containing that ugly #ifndef just once. It's a common practice anyway.
You can define prefixes for your platform as macro. Like
#define STRINGY(STR) #STR
#define SAFE_INCLUDE(HDR) STRINGY(HDR)
#ifndef IS_AS400
#define SAFE_INCLUDE(LIB) STRINGY(*LIBL/H/##LIB)
#else
#define SAFE_INCLUDE(LIB) STRINGY(LIB##.H)
#endif
and you can use this as
#include SAFE_INCLUDE(MYLIB)
There are two better solutions:
Use your Makefiles to properly set a path where compiler looks for includes.
For GCC you add to CFLAGS -I <path> (you can do that multiple times).
Wrap the non-compliant libraries with your own header files.