Get the included path in same program - c

Suppose I have a program
main.c
#include "file.h"
#include <stdio.h>
int main()
{
//Code to found the included path
}
gcc -I /local main.c
How can I found the included path of header file inside this program
Now their can be 3 included path
current directory
ENV set in the Path VARIABLE or other
Directory included with -I option
Please provide a way to get this inside the same program.

For the include files that you could edit you can use the __FILE__ macro. It makes the preprocessor insert the full file's name like /the/directory/filename.
Just add the follow line to you header:
static const char MyIncludeFileName[] = __FILE__;
If you do not refer to MyIncludeFileName (from the code which includes the header) the compiler might issue a warning that MyIncludeFileName is declared but not used. To tell the compiler be quiet about this do the followings:
static const char MyIncludeFileName[] __attribute__ ((unused)) = __FILE__;

Related

GCC warn when relative import file multiple times in include path list

If a header filename exists multiple times in include path list, how can I make GCC warn me or error out, instead of choosing silently proceeding?
Consider this example:
// File: alternative_1/my_include.h
#define VAL 1
// File: alternative_2/my_include.h
#define VAL 2
// File: main.c
#include <stdio.h>
#include "my_include.h"
int main(void) {
printf("Using alternative_%d\n", VAL);
}
I do not want this to silently compile and run:
❯ gcc -Ialternative_2 -Ialternative_1 main.c -o main
❯ ./main
Using alternative_2
// File: alternative_1/my_include.h
int function() {
return 1;
}
It is wrong. Yuo should not put any function bodies and data definitions into header files. They should only contain types declarations, definitions, extern objects declarations and static inline functions.
And answering your question - compilers only search include paths until they found the include file. Then they stop to search the rest of the directories. There is no way of changing it.

how can I force the source file implement definition for a header file

below is the code:
//test.h
...
extern int globalVariable;
...
//test.c
#include "test.h"
...
int globalVariable = 2020;
...
//main.c
#include <stdio.h>
#include "test.h"
int main()
{
printf("Value is %d", globalVariable);
}
let's say in a scenario, there are hundreds of variables are declared in test.h and globalVariable is just one of them.
since there are two many variables, I easily makes a typo error in test.c as:
#include "test.h"
int globalVariables = 2020; //extra 's' in the name which contradicts the declaration of its counterpart in test.h
if I compile(only compile,not linking them) test.c, test.h and main.c, it compiles and shows no error. the unresolved error will only occur when linker involved in the linking stage.
But in a large application, I might just write some modules without the need of linking all existing to an executable file, so it would be better the compiler throw an error in the compile stage to indicate the error so I can correct them asap, so how can I let the compiler force the source file implement definition for a header file?
You could also use the preprocessor
test.h:
#ifndef TEST_C_IMPLEMENTATION
#define DEFINE_AND_INIT_VARIABLE(type, name, value) \
extern type name;
#else
#define DEFINE_AND_INIT_VARIABLE(type, name, value) \
type name = value;
#endif
DEFINE_AND_INIT_VARIABLE(int, globalVariable, 2020);
test.c:
#define TEST_C_IMPLEMENTATION
#include "test.h"
This technique can be taken even further - there are small utility libraries that are shipped as a single include file; you're just to set a macro in one of the translation units to force the implementation to be compiled in there.
The declaration extern int globalVariable; says that the variable exists somewhere, but not necessarily in the current translation unit. So any source file that includes the header containing this declaration will know that the variable exists without needing the full definition.
When you then get to the linking stage is when you'll get the error regarding glovalVariable being undefined. Since the variables is declared in test.h, convention would dictate that the definition would be in test.c. Upon inspecting that file, you would then find that no such variable exists and could then either add it or find the typo and fix it.

undefined reference when including a header file

I get an error when I include a header file, but not if I include the source file instead.
The function is defined in the source file like this:
/* in User.c */
struct User {
const char* name;
};
struct User* addedUser(const char* name) {
struct User* user = malloc(sizeof(struct User));
user->name = name;
return user;
}
And used like this:
/* in main.c */
int test_addedUser() {
char* newName = "Fooface";
struct User* newUser = addedUser(newName);
assert(!strcmp(newName, newUser->name));
return 0;
}
This works great. I am able to call test_addUser without a problem when I #include "User.c".
However, I would like to #include "User.h" instead, which is located in the same directory:
/* in User.h */
struct User {
const char* name;
};
struct User* addedUser(const char*);
But, if I #include "User.h" instead of User.c, I get an error:
CMakeFiles/run_tests.dir/src/tests.c.o: In function `test_addedUser':
/home/rid/port/src/tests.c:(.text+0x4eb): undefined reference to `addedUser'
It seems strange to me that the reference works just fine when including the source file User.c but it is unable to reconcile User.h.
Any ideas why this might be?
#include means that the file included is copied into the source file.
So when you include your .c file, the function's code is here and it works.
If you include only the header file, it's good thanks to that your functions will know each other, at least they will now they exist but they need their code to work together, so you need now to compile your two files.c together, not one by one.
Maybe you're compiling by yourself :
gcc file1.c file2.c
Or with an IDE, you have to adjust the compiling options.
If you want to compile the C files separatly, you have to compile them in object files (-c option with gcc), then link them.
So I created some custom lib folder for example "engine" and placed some .cpp files in it:
main.cpp
engine/sprite.cpp
engine/sprite.h
engine/unit.cpp
engine/unit.h
So before compile cmd looked like:
g++ -o main main.cpp
After adding folder:
g++ -Iengine -o main main.cpp engine/*cpp
And it works

Are #define (preprocessor directives) inherited from header files

If I have some #define in a header file, will it be usable in a source code that includes that header?
[Something like #define Bytef unsigned int]
Yes you can do that.
An include works as follows:
imagin you have a file.
header.h
content:
void HappyMakerPrototype();
void AnotherPrototype();
and a source file
src.c
content:
void dummydec();
#include "header.h"
void main ()
{
return;
}
In the first step of compilation it will run through the preprocessing.
Here the include line just gets replaced by all the content of your included file.
So that If you would request the output for the preprocessed file it would look like:
(in gcc and clang compiler you can request the preprocessed file with parameter -E I guess that will help you understanding)
void dummydec();
void HappyMakerPrototype();
void AnotherPrototype();
void main ()
{
return;
}
Yes you can do. While you are including that header file it will inherit all the things from that header. So you can use that Macro.
Yes. Including a file is as the same as if you copy and pasted the contents of the header file at the exact location as the #include directive.

Duplicate header files throughout source files?

// File foo1.c :
#include <stdio.h> // once
void foo1(void);
void foo1(void){
puts("foo1");
}
// File foo2.c :
#include <stdio.h> // again
void foo2(void);
void foo2(void){
puts("foo2");
}
// File foomain.c :
#include <stdio.h> // yet again
void foo1(void); // again
void foo2(void); // again
int main(void){
foo1();
foo2();
puts("foomain");
return 0;
}
// create object files
gcc -fPIC foo1.c -o foo1.o // 1 stdio.h
gcc -fPIC foo2.c -o foo2.o // 1 stdio.h
// create shared library
gcc -fPIC -shared foo1.o foo2.o -o foo.so // foo.so contains stdio.h 2 times ?
// build entire program
gcc foo.so foomain.c -o foomain // foomain contains 1 stdio.h plus the 2 from foo.so ?
Why does the entire program contain 3 stdio.h ? Seems redundant, why not just 1 ? Shouldn't the compiler need only 1 ?
It makes sense for the object files to contain a prototype but why do they have to be specified again in foomain.c ? Shouldn't the compiler know they are already specified in foo.so ?
That's because each file is compiled separately, so each time the compiler should know the signatures of all functions used to perform compile-time checks. So, each file has to contain all declarations used, which are included by the preprocessor before the file is compiled.
If you look at the top of most header files they have an include guard to stop double inclusion.
#ifndef FOO
#define FOO
#endif
See Include Guard for more information.
The #include lines are not actually a part of the compiler, but the C preprocessor.
What the preprocessor does with #include lines is to actually include the file into the source, and creates a new temporary file containing the contents of your file with the #include line replaced by the contents of the file being included.
You don't actually need the include file at all, if all you are doing is calling functions. You might get warnings about the functions not being declared, but those can be adding the prototypes for those functions yourself. For example, in your main source file you only use puts, instead of including <stdio.h> you can add a prototype like this:
int puts(const char *s);
However, <stdio.h> also defines some structures (like the FILE structure) and declares some variables (like stdout) and if you use any of those you need the header file as well.
You can use include guards as #Jeff suggested or just put #pragma once at the top of each header.

Resources