I want to use a macro defined in different header files with the same name and different implementations.
I have two header files h1.h and h2.h. In the first header file I defined:
#define PRINT printf(" hi , macro 1\n");
and in the second header file
#define PRINT printf(" hi , macro 2\n");
in main() when I try to use PRINT it is printed depending on the order of inclusion.
I found some similar problems and they used a wrapper, by including the first header file then defining an inline method:
inline void print1() {
PRINT();
}
and then undefining PRINT and including the second header file. In main() when I call print1() and PRINT I got the output from them both.
My missing point is how after we have undefined the PRINT from the first header file we are still able to have it - in other words what happens when we call it inside the inline function? Did the compiler copy the value of PRINT and assign it to the function and save the function in some way?
If I understand correctly, something like this is happening:
#include "h1.h" // defines PRINT: printf(" hi , macro 1\n");
inline void print1(){
PRINT();
}
#undef PRINT
#include "h2.h" // defines PRINT: printf(" hi , macro 2\n");
Nothing weird happens though. The pre-processor substitues PRINT inside the inline function before it is un-defined. So in the resulting code (you can see this when you compile with the -E flag for GCC), it becomes this:
// contents of h1.h...
inline void print1(){
printf(" hi , macro 1\n");
}
// contents of h2.h...
#defined macros are only kept for the duration of the pre-processing, and are substituted as the pre-processor goes along. Similar to variables in normal programming, if you re-assign it the pre-processor will just use the new value for following occurrences.
It works because during compilation the pre-processor reaches the PRINT() call in print1, evaluates the macro, and replace it with its current value. Then, if I understand correctly, later (in the next lines) you redefine or undefine PRINT (be it by including another header), then any further reference to it will make the pre-processor replace it with its current value again (which is now different), therefore you get 2 distinct behaviours calling the "same" macro.
Related
I saw some piece of code in one of the old files.
void (*const m_exec[N_EXECS])(void) =
{
#define PROCESS_DEF_TIMED(name) name, // defines macro for use in proclist.h
#define PROCESS_TIMED // define switch for section in proclist.h
#include "proclist.h"
#undef PROCESS_TIMED // undefine switch
#undef PROCESS_DEF_TIMED // undefines macro
};
I am unable to understand the meaning of this code. Is this a function pointer with declaration and function definition together? But if I try to declare similar function pointer like below, I get compilation error
void (*voidFptr)(void) =
{
printf("Hello\n");
}
Also what is #define here? Why this is inside the function I am not sure.
This:
void (*const m_exec[N_EXECS])(void)
is the way you declare an array of function pointers in C. You are not alone in finding this difficult to read. It declares an array of length N_EXECS, where each element in the array is a function that takes no arguments and returns a pointer to a const-void.
The braces-enclosed block after it is the array initializer; probably proclist.h has a whole list of function pointer declarations in it, and this is essentially pasting those into this array. If you want to see what's actually happening after the #include, you can use the -E flag of your compiler. So if this were in main.c, you would run:
gcc -E -Ipath/to/headers -Iother/path/to/headers main.c
And it would give you a (probably huge) dump of source code, which is the result of pushing that file through the preprocessor and evaluating all of the #include statements.
Edit: missed your last question.
Probably (and this is conjecture without seeing proclist.h), the things its defining change the contents of proclist.h. For example, if it contained:
#ifdef PROCESS_TIMED
&function1_timed,
&function2_timed
#else
&function1,
&function2
#endif
Then #define PROCESS_TIMED would change what ended up in your m_exec array.
I'm trying to explain this satisfactorily, but when I call a function I want it to virtually insert itself into the main function's code in the place where I call it, so I can save typing it out multiple times, however it directly affects variables defined in the scope of the main function. What's the best way to achieve this?
EDIT: I should probably make it clear I also want it to take a single argument.
Sounds like you need a preprocessor macro. These aren't real functions, but blocks of code the the preprocessor replaces before compiling the code. E.g., consider a simple macro to increment a number:
#include <stdio.h>
#define INC(x) (x)++
int main() {
int a = 1;
INC(a);
INC(a);
printf("%d\n", a);
return 0;
}
The text INC(a) will be replaced with a++, so running this program will print out 3 (1 after two increments).
void fun()
{
// Essentially this is a function with an empty body
// And I don't care about () in a macro
// Because this is evil, regardless
#define printf(a, b) (printf)(a, b*2)
}
void main() // I know this is not a valid main() signature
{
int x = 20;
fun();
x = 10;
printf("%d", x);
}
I am having doubt with #define line ! Can you please give me some links documentation for understanding this line of code.Answer is 20.
The #define defines a preprocessor macro is processed by the preprocessor before the compiler does anything.
The preprocessor doesn't even know if the line of code is inside or outside a function.
Generally macros are defined after inclusion of header files.
i.e. after #include statements.
Preprocessor macros are not part of the actual C language, handling of macros and other preprocessor directives is a separate step done before the compiler1. This means that macros do not follow the rules of C, especially in regards to scoping, macros are always "global".
That means the printf function you think you call in the main function is not actually the printf function, it's the printf macro.
The code you show will look like this after preprocessing (and removal of comments):
void fun()
{
}
void main()
{
int x = 20;
fun();
x = 10;
(printf)("%d", x*2);
}
What happens is that the invocation of the printf macro is replaced with a call to the printf function. And since the second argument of the macro is multiplied by two, the output will be 10 * 2 which is 20.
This program illustrates a major problem with macros: It's to easy to a program look like a normal program, but it does something unexpected. It's simple to define a macro true that actually evaluates to false, and the opposite, changing the meaning of comparisons against true or false completely. The only thing you should learn from an example like this is how bad macros are, and that you should never try to use macros to "redefine" the language or standard functions. When used sparingly and well macros are good and will make programming in C easier. Used wrongly, like in this example, and they will make the code unreadable and unmaintainable.
1 The preprocessor used to be a separate program that ran before the compiler program. Modern compilers have the preprocessor step built-in, but it's still a separate step before the actual C-code is parsed.
Let me put this in another way.
printf() is an inbuilt standard library function that sends formatted output to stdout (Your console screen). The printf() function call is executed during the runtime of the program. The syntax looks likes this.
int printf(const char *format, ...)
But this program of yours replaces the printf() function with your macro before the compilation.
void fun(){
#define printf(a, b) printf(a, b*2)
}
void main() {
int x = 20;
fun();
x = 10;
printf("%d", x);
}
So what happens is, before compilation the compiler replaces the inbuilt function call with your own user defined macro function with two arguments:
a="%d" the format specifier and
b=the value of x =10.
So the value of x*2 =20
Hi guys trying to use two main() and getting this error multiple definition of main(). I renamed my main functions then why is this error and also first defined here for my print().
header file:
#ifndef TOP_H_
#define TOP_H_
#include <stdio.h>
#include <string.h>
#define onemain main
#define twomain main
inline void print();
#endif /* TOP_H_ */
c file one:
#include "top.h"
void print();
int onemain()
{
print();
return 0;
}
void print()
{
printf("hello one");
}
c file two:
#include "top.h"
void print();
int twomain()
{
print();
return 0;
}
void print()
{
printf("hello two");
}
Basically any C (or even C++) program is a bunch of functions calling each other.
To begin a program execution, you have to pick one of these functions and call it first.
By convention, this initial function is called main.
When you include several source files in a project, the IDE compiles them all, then calls the linker which looks for one single function called main and generates an executable file that will call it.
If, for any reason, you defined two "main" functions inside all these files, the linker will warn you that it cannot choose on its own which one you intended to be the starting point of your program.
The macro substitution of onemain and twomain occurs before the compiler proper sees the program, so that doesn't make a difference. The functions are both named main.
C++ allows different functions with the same name, but does not allow two definitions of the exact same function signature. There would be no way to form a function call expression that would reach either overload. Additionally, the functions are the same entity, and one thing cannot have two definitions.
In addition, in C++ main cannot be overloaded, because the program is supposed to start when the unique main function is called, and any given system detects what format of main the particular program uses, out of a variety of allowed formats. (This auto-detection feature also applies to C.)
But you are not asking about C++; in C, without function overloading, there are no redefinitions of the same name, even for different signatures. Each name of extern linkage in C uniquely identifies an entity, so you cannot have two.
It's unclear what you want the resulting program to do. Most likely you need to build two separate programs.
I don't get what you ask - your error messages are quite clear:
You have 2 definitions of print(), which will collide. Remove one.
You as well have 2 definitions of main() - your #defines will replace your onemain and twomain functions, naming them effectively as main.
You overrode the built in print, about main, try imagining a car with two steering wheels ... it wont work ...
Your C program has two have a least one main, so the computer knows where the program starts.
If you have 2 files with two main function, then you have two different programs.
It's not possible for a C program to have more than one main() in it. Also, main() should be declared as an int and return an integer value (usually 0).
I am a beginner to C programming and I'm trying out different methods and experimenting with small programs.
I have four files. two header files and two source files. I want to:
Declare a variable (Actually two variables and a char) and a
function (from the second source file) in one header file.
Define these variables and assign values to them in a second header
file(variables from point 1).
Write a function including these two header files and using the
values from these files(point 2) in one source file (without a main-
just a function definition using the variables).
Have a main source file that invokes the function from the second
source file (from point 3.)
How do I come about this? I have included both header files in both the .c files. But when I try to compile and link it (using GCC in Linux) I get a
multiple definition ... first defined here error for all the variables.
I have looked at these answers First and Second
I didn't quite understand the answers in the Second as I'm not able to figure out how to use header guards.
I am not able to figure out how to check all of the boxes (points one through 4).
header1.h
extern int i,j; extern char c;
void ad_d();
header2.h
int j=6;int i=7;
char c='x';
fnfile.c
#include "header1.h"
#include "header2.h"
#include<stdio.h>
void ad_d()
{
i+=j;
printf("\n %d \t %c \n", i,c);
}
filemain.c
#include<stdio.h>
#include "header1.h"
#include "header2.h"
void main()
{
ad_d();
}
You can only define a variable once, that allcoates space in memory where the value will be stored. you can then declare the variable in each file (or better yet in a common header file) which will tell the compiler that a varialble of that name and type will be defined in one of the compiled files, and can be found at a later stage.
in the file where you want to define the variable use:
int my_global = 0; /* always good practice to initalize */
in other files (or a common header) use:
extern int my_global;
Now you can read or write my_global from any file where it is declared.
The header guard stuff is an attempt to move the definition and declaration into the same statement, at your level it is probably best that you get a handle on declaration vs definition before trying to play games like that.
int j=6;int i=7;
char c='x';
You don't want these in a header file, as they're definitions. Put them in the C file instead, and just include the same header in both files (with the extern declarations of the variables).
As it stands, both of your source files are trying to define these variables, which is why you get the error.