#define not working as expected after #undef using #ifndef - c

I wrote a simple program to change addition to multiplication
#include<stdio.h>
#define ADD(X,Y) X+Y
void fun()
{
#ifndef ADD(X,Y)
printf("entered #ifndef");
#define ADD(X,Y) X*Y;
#endif
int y=ADD(3,2);
printf("%d",y);
}
int main()
{
#undef ADD(X,Y)
fun();
return 0;
}
The output I expect is 3*2 but the code still outputs 3+2 i.e. 5 .
The code doesn't output : "entered #ifndef", that means #undef is not working?
What is wrong here?
Edit :
Thanks to #deviantfan
Here is the correct code:
#include<stdio.h>
#define ADD(X,Y) X+Y
void fun();
int main()
{
#undef ADD(X,Y)
fun();
return 0;
}
void fun()
{
#ifndef ADD(X,Y)
printf("entered #ifndef");
#define ADD(X,Y) X*Y;
#endif
int y=ADD(3,2);
printf("%d",y);
}

The preprocessor (which processes eg #define) doesn´t know about
functions or things like that. It processes the file strictly from top to bottom,
independent how the actual code execution would jump around at runtime.
As soon as it hits your #undef, the #ifndef is long forgotten and won´t be evaluated again.

The actual solution to this problem is to use function pointers.
Here is a direct translation from your current code to function pointers.
Note the similarities and differences.
#include <stdio.h>
int actual_add(int X, int Y) {
return X+Y;
}
int actual_multiply(int X, int Y) {
return X*Y;
}
int (*ADD)(int,int) = actual_add;
void fun()
{
if (!ADD)
{
printf("entered #ifndef");
ADD = actual_multiply;
}
int y=ADD(3,2);
printf("%d",y);
}
int main()
{
ADD = NULL;
fun();
return 0;
}

The #ifdef, #ifndef and #undef preprocessor directives expect an identifier, not an expression.
#ifndef ADD(X,Y) is meaningless.
It should read: #ifdef ADD.
The same goes for #undef ADD

Related

How can i use printf in a function with checking a variable?

I want to print output if OUT is 1. So i think that code.
#define OUT 1
void d_printf(char *text){
if(OUT)
printf("%s", text);
}
int main(void){
d_printf("%d\n", 5);
return 0;
}
But my parametre is char*, i can't send %d, 5. How can i solve this?
You can use a simple macro:
#include <stdio.h>
#define OUT 1
#define d_printf OUT && printf
int main(void) {
d_printf("%d\n", 5);
return 0;
}
If you get compiler warnings about an unused expression, you can use a more elaborate macro:
#include <stdio.h>
#define OUT 1
#define d_printf(...) do { if (OUT) printf(__VA_ARGS__); } while(0)
int main(void) {
d_printf("%d\n", 5);
return 0;
}

C: Include a file which includes a file that also needs to be included in the main program

I have a header file (generalfunctions.h):
#ifndef GENERALFUNCTIONS_H
#define GENERALFUNCTIONS_H
//functionsdeclartion for example
int getInt(char* text);
#endif /* GENERALFUNCTIONS_H */
and a C file generalfunctions.c where I include this headerfile (so I can use some of the functions within each other and don't have bother with their order) and code out the functions.
generalfunctions.c:
#include "generalfunctions.h"
#include <stdlib.h>
#include <stdio.h>
//functions implentaion for example
int getInt(char* text){
int i;
printf("%s\n", text);
if(scanf("%d", &i)==EOF){
printf("INT_ERROR\n");
exit(1);
}
while (fgetc(stdin) != '\n');
return i;
}
//...
Now I need some of these functions in a file called project_objects.c that together with project_objects.h defines a couple of structs, unions, variables and functions with these things I need for my project.
project_objects.h:
#ifndef POINT_H
#define POINT_H
typedef struct point{
int x;
int y;
} point;
point create_point(void);
void print_point(point *p);
//...
#endif /* POINT_H */
project_objects.c:
#include <stdlib.h>
#include <stdio.h>
#include "project_objects.h"
#include "generalfunctions.h"
point create_point(void){
point p;
p.x=getInt("Give my a x");
p.y=getInt("Give my a y");
return p;
}
void print_point(point *p){
printf("x: %d\n", p->x);
printf("y: %d\n", p->y);
}
//..
However I also need some of the functions described in generalfunctions.h directly in my main program:
#include "generalfunctions.c"
#include "project_objects.c"
#include <stdlib.h>
#include <stdio.h>
int main(void){
int i=getInt("How many points would you like to create?");
while(i<1){
i=getInt("Cannot create a negative number of points. How many points would you like to create?");
}
point pointarray[i];
for(int j=0; j<i; j++){
pointarray[j]=create_point();
}
for(int k=0; k<i; k++){
printf("Point %d:\n", k+1);
print_point(pointarray+k);
}
return EXIT_SUCCESS;
}
This seems to work. If I just include the h-files than I get the error that getInt() isn't defined when I link. And before when I included the C file for general functions in project_object.c I got errors for duplication. But now the files seem more dependent on each other than I planned. I also don't understand why this works.
Do not include .c-files. Write function protytypes in .h-files and include them.
project_object.h
typedef int faa;
foo.h
include "project_object.h"
faa foo( faa x ); // prototype for function "foo"
foo.c
#include "foo.h"
faa foo( faa x ) // implementation of function "foo"
{
return x + 666;
}
main.c
#include "project_object.h"
#include "foo.h" // include .h-file with prototype of function "foo"
int main( void )
{
faa x;
x = foo(0); // call function "foo"
return 0;
}

Invalid conversion from int* to int using functions

I have this "simple" problem: I have in input 2 int numbers and i must output them in decreasing order.
#include <stdio.h>
#include <iostream>
int fnum()
{
int NUM;
scanf("%d",&NUM);
return NUM;
}
void frisultato(int x,int y)
{
if (x>y)
{
printf("%d",x);
printf("%d",y);
}
else
{
printf("%d",y);
printf("%d",x);
}
return;
}
int main()
{
int A,B;
A=fnum;
B=fnum;
frisultato(A,B);
}
I recieve an error at
A=fnum;
B=fnum;
my compiler says: invalid conversion from int(*)() to int.
This is the first time i use functions, what is the problem? Thank you!
Michelangelo.
A=fnum;
B=fnum;
You're not actually calling the function fnum here. You're attempting to assign a pointer to the function to the int variables A and B.
To call the function, do this:
A=fnum();
B=fnum();
Sorry, but since you seem to be new at programming, I couldn't help but refactor/comment on your code:
#include <stdio.h>
#include <iostream>
int fnum()
{
int num;
scanf("%d",&num);
return num;
}
void frisultato(int x, int y)
{
if (x>y)
{
printf("%d",x);
printf("%d",y);
}
else
{
printf("%d",y);
printf("%d",x);
}
/* No need to return in void */
}
int main()
{
/*
Variables in C are all lowercase.
UPPER_CASE is usually used for macros and preprocessor directives
such as
#define PI 3.14
*/
int a, b;
a = fnum(); //Function calls always need parenthesis, even if they are empty
b = fnum();
frisultato(a, b);
/*
Your main function should return an integer letting whoever
ran it know if it was successful or not.
0 means everything went well, anything else means something went wrong.
*/
return 0;
}
Also, don't sign your name on StackOverflow questions.

How to use macros?

Why the answer is a=71? Why doesn't at the end of running this program the answer would be according to: m1(3,2,1)=7 ....a=m2(7,21,14)=7*21+14
#define m1(a,b,c) a*b+c
#define m2(x) m1( (x), (x*3), (x*2))
int main()
{
int a;
a=m2(m1(3,2,1));
return 0;
}
If you compile with -E flag (which runs the preprocessor only, you get:
int main()
{
int a;
a=(3*2 +1)*(3*2 +1*3)+(3*2 +1*2);
return 0;
}

Macros print output

#include <stdio.h>
#define N 100
void f(void);
int main(void)
{
f();
#ifdef N
#undef N
#endif
return 0;
}
void f(void){
#if defined(N)
printf("N is %d\n",N);
#else
printf("N is undefined\n");
#endif // defined
}
Why does this output print N is undefined shouldn't it print N is 100 because of the function call on f before it reaches the undef that removes the value 100?
Preprocessor directives and macros are processed at a very early stage of compilation, they have no existence at runtime.
Running your code just through the preprocessor (cpp -P -- warning: remove the #include first) shows the actual C code that is being compiled.
void f(void);
int main(void)
{
f();
return 0;
}
void f(void){
printf("N is undefined\n");
}
As to why this expansion is chosen rather than the alternate message, consider these lines in your source.
#ifdef N
#undef N
#endif
Regardless of whether it's defined or not initially, it will not be defined after these lines are (pre-)processed.

Resources