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.
Related
This is my code. I have file1.c and file2.c. I want to call the MESSAGE from file2.c but I can't seem to do it. I am newbie in C so I really don't know what to do. I researched already but, I can't seem to find a specific answer. Thankyou.
#define MESSAGE "this is message!"
helloworld(){
printf("%s",MESSAGE);
getch();
}
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file2.c"
int main(void)
{
helloworld();
}
There are a few misconceptions you have: First of all the concept of "calling" a macro. It's not possible, even if a macro looks like a function it's not a function and macros are not actually handled by the compiler. Instead macros are part of a separate language that is handled by a preprocessor, which takes the source file and modifies it to generate a translation unit that the compiler sees. (For more information about the difference phases of "compilation" see e.g. this reference.)
The preprocessor does this by basically doing a search-replace in the input source file: When it sees a macro "invocation" it simply replaces that with the "body" of the macro. When it sees an #include directive, it preprocesses the file and then puts the content in place of the directive.
So in your code, when the preprocessor sees the macro MESSAGE it is literally replaced by "this is message!". The actual compiler doesn't see MESSAGE at all, it only sees the string literal.
Another misconception is how you use the #include directive. You should not use it to include source files. Instead you compile the source files separately (which creates object files) and then link the generated object files together with whatever libraries are needed to form the final executable.
To solve the problem of macros (and other declarations) being available to all source files, you use header files. These are like source files, but only contains declarations and macros. You then include the header file in both source files, and both source files will know about the declarations and macros available in the header file.
So in your case you should have three files: The main source file, the source file containing the function, and a header file containing the macro and the function declaration (also known as a prototype). Something like
Header file, e.g. header.h:
// First an include guard (see e.g. https://en.wikipedia.org/wiki/Include_guard)
#ifndef HEADER_H
#define HEADER_H
// Define the macro, if it needs to be used by all source files
// including this header file
#define MESSAGE "this is message!"
// Declare a function prototype so it can be used from other
// source files
void helloworld();
#endif
Main source file, e.g. main.c:
// Include a system header file, to be able to use the `printf` function
#include <stdio.h>
// Include the header file containing common macros and declarations
#include "header.h"
int main(void)
{
// Use the macro
printf("From main, MESSAGE = %s\n", MESSAGE);
// Call the function from the other file
helloworld();
}
The other file, e.g. hello.c:
// Include a system header file, to be able to use the `printf` function
#include <stdio.h>
// Include the header file containing common macros and declarations
#include "header.h"
void helloworld(void)
{
printf("Hello world!\n");
printf("From helloworld, MESSAGE = %s\n", MESSAGE);
}
Now, if you use a command-line compiler like gcc or clang then you can simply build it all by doing e.g.
$ gcc -Wall main.c hello.c -o myhello
That command will take the two source files, main.c and hello.c and run the preprocessor and compiler on them to generate (temporary) object files. These object files are then linked together with the standard C library to form the program myhello (that's what the option -o does, names the output file).
You can then run myhello:
$ ./myhello
From main, MESSAGE = this is message!
Hello world!
From helloworld, MESSAGE = this is message!
In your file1.c, MESSAGE is a preprocessor macro, which means the text MESSAGE will be replaced with the string "this is message!". It is not visible outside the file. This is because in C, translation units are the final inputs to the compiler, and thes translation units already have all of preprocessor macros replaced by the tokens of the corresponding argument.
If you want to have a common variable, you should declare the variable as extern in a .h header file, and then #include the file where you need to use it.
see Compiling multiple C files in a program
You have to put your #define in a .h file and include it in .c files where you want to use it.
You can write the files as below and compile the code as i mention in the following steps.
file1.h
#ifndef _FILE1_H
#define _FILE1_H
#define MESSAGE "this is message!"
extern void helloworld();
#endif
file1.c
#include "file1.h"
helloworld()
{
printf("%s",MESSAGE);
getch();
}
file2.c
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file1.h"
int main(void)
{
helloworld();
return 0;
}
For compiling,
gcc -Wall file1.c file2.c -o myprog
./myprog
Here is code try this:
In File1.C
#define FILE1_C
#include "file1.h"
helloworld()
{
printf("%s",MESSAGE);
getch();
}
In File2.C
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "file1.h"
int main(void)
{
helloworld();
}
In File1.h
#ifdef FILE1_C
#define MESSAGE "this is message!"
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN helloword()
i have the following files
(its pseudo code, and i know the define, undef is ugly, but i would need it for some project)
if i compile those files and link them together - it seems to work - that in file3, file1 - MYVAL == 1
is it safe to assume this, that the preprocessor stuff is done file-by-file?
conf.h:
#define MYVAL 1
src1.c
#include "conf.h"
int maint(int argc, char ** argv) {
printf("%d", MYVAL);
}
src2.c
#include "conf.h"
void demo() {
#undef MYVAL
#define MYVAL 2
printf("%d", MYVAL);
}
src3.c
#include "conf.h"
void demo2() {
printf("%d", MYVAL);
}
regards
Preprocessing is done per translation unit before the compilation phase (so way earlier than the linkage phase). In your case the preprocessor will expand that macro in each of your .c files individually based on your inclusion of the conf.h header file.
is it safe to assume this, that the preprocessor stuff is done file-by-file?
Basically in your case yes. Each of your .c files is a distinct translation unit. (Unless they start including each other or something) They are preprocessed separately, compiled and then their objects get linked together.
When you #include "conf.h" its code is placed instead of this line. This is the preprocessor's work. So, this define sentence is placed in each file.
But if you do #define work(n) funcCall((n)) and work(5); then, it'll fail if funcCall is not defined in any of your files.
Yes, the preprocessor is used for each source file. It generates a preprocessed file from the source file and all include files that is actually passed to the C compiler.
When you #define something in a include file it gets in the preprocessed file. #defines in other source file doesn't care.
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__;
I have two source files:
Source FIle 1 (assembler.c):
#include "parser.c"
int main() {
parse_file("test.txt");
return 0;
}
Source File 2 (parser.c):
void parse_file(char *config_file);
void parse_file(char *src_file) {
// Function here
}
For some reason, when compiling it is giving me the following error:
duplicate symbol _parse_file in ./parser.o and ./assembler.o for architecture x86_64
Why is it giving me a duplicate symbol for parse_file? I am just calling the function here... No?
First off, including source files is a bad practice in C programming. Normally, the current translation unit should consist of one source file and a number of included header files.
What happens in your case is that you have two copies of the parse_file function, one in each translation unit. When parser.c is compiled to an object file, it has its own parse_file function, and assembler.c also has its own.
It is the linker that complains (not the compiler) when given two object files as an input, each of which contains its own definition of parse_file.
You should restructure your project like this:
parser.h
void parse_file(char *);
parser.c
void parse_file(char *src_file) {
// Function here
}
assembler.c
/* note that the header file is included here */
#include "parser.h"
int main (void) {
parse_file("test.txt");
return 0;
}
You're including the parser.c file, which means all the code that is in that file will be "copied" to assembler.c file. That means that the entire contents of parser.c will be compiled when the compiler is compiling parser.c, and then it'll be compiled again when the compiler is compiling assembler.c
That's what headers are for.
In the header you can put only the declarations, so you can include it without creating the same symbols again in a different translation unit.
so you can just create a parser.h containing just the declaration of the function:
void parse_file(char *config_file);
then in your assembler.c you include just the header:
#include "parser.h" //include the header, not the implementation
int main() {
parse_file("test.txt");
return 0;
}
You are including the .c file which contains the definition of the function parse_file. Thus it is defined twice, once in each translation unit, which is not allowed.
As other answers state, including the source means the file will be copied to parser.c and will be defined there as well in the original place (assembler.c). To solve this, either create a header file with your prototype:
parser.h
void parse_file(char *config_file);
And include that file:
assembler.c
#include "parser.h"
int main() {
parse_file("test.txt");
return 0;
}
Or remove the include and provide a clue to the function:
int main() {
void parse_file(char *);
parse_file("test.txt");
return 0;
}
Or even simply remove the include at al. Not good practice, as the compiler (without information on a function) will consider its returned value is an integer and may cause other warnings.
I had to write few functions which are very long. So, I decided to put them in different files and link them to main.. so that it works as if I wrote function definitions after main().
How do I do it..
In a .h file you put your prototype
#ifndef MY_HEADER_H
#define MY_HEADER_H
void hello(void);
#endif
In a seperate .c file you implement your function such as hello.c
#include "myheader.h"
void hello()
{
printf("Testing function from other file\n");
}
then in main you do
#include "myheader.h"
int main()
{
hello();
return 0;
}
make sure you compile hello.c into hello.o before linking the files or it will tell you that it can't resolve the reference to hello.
Find create a header file that has a file ending of .h .
Lets say this header file is named blah.h.
The general structure of this header will be
#ifndef BLAH_H_INCLUDED
#define BLAH_H_INCLUDED
//code
#endif // BLAH_H_INCLUDED
Those are header guards, to prevent multiple inclusions.
Inside the code you will still your function declarations.
For example, void function(int blah); would be a valid function declaration.
This file is then included at the top of all of your files that uses or defines the functions declared, #include "blah.h"
Then you can define your functions in the other files, and when you link them together the program will work.