Source Code: Even or Odd Number using Macros: C Program
#include<stdio.h>
#define ODD_EVEN(num) ( (num % 2 == 0) ? printf("Even\n") : printf("ODD\n") )
int main()
{
int num;
printf("Enter a positive number\n");
scanf("%d", &num);
ODD_EVEN(num);
return 0;
}
Output 1: Enter a positive number 5 ODD
Output 2: Enter a positive number 6 Even
In above program the macro template ODD_EVEN(num) will be replaced by it’s macro expansion ( (num % 2 == 0) ? printf(“Even\n”) : printf(“ODD\n”) ) and hence if the user input number is perfectly divisible by 2, then EVEN will be printed else ODD will be printed.
Source Code: C Program To Determine Leap Year or Not using Macros
#include<stdio.h>
#define NOT_LEAP(x) printf("%d is not leap year\n", x)
#define LEAP_YEAR(x) printf("%d is leap year\n", x)
#define LEAP(x) ( (x % 100 == 0 && x % 400 == 0) ? LEAP_YEAR(x) : \
( (x % 4 ==0) ? LEAP_YEAR(x) : NOT_LEAP(x)) )
int main()
{
int year;
printf("Enter a year\n");
scanf("%d", &year);
LEAP(year);
return 0;
}
Output 1: Enter a year 2018 2018 is not leap year
Output 2: Enter a year 2019 2019 is not leap year
Output 3: Enter a year 2020 2020 is leap year
Output 4: Enter a year 2023 2023 is not leap year
Output 5: Enter a year 2024 2024 is leap year
In above program we’re writing NOT_LEAP(x) macro to display a message that the user input year is not a leap year. LEAP_YEAR(x) macro is used to display message that the user input year is a leap year.
We use both NOT_LEAP(x) and LEAP_YEAR(x) macro names or macro templates inside LEAP(x) macro expansion.
We’re also using macro continuation(\) to break the line and continue writing the logic in next line in macro expansion of LEAP(x).
Source Code: Biggest of 3 Numbers using Macros: C Program
#include<stdio.h>
#define BIGGEST(x, y, z) ( (x > y && x > z) ? x : ( y > z) ? y : z )
int main()
{
int a, b, c;
printf("Enter 3 integer numbers\n");
scanf("%d%d%d", &a, &b, &c);
printf("Biggest of 3 numbers is %d\n", BIGGEST(a, b, c));
return 0;
}
Output: Enter 3 integer numbers 20 50 60 Biggest of 3 numbers is 60
Here we’re writing logic inside macro expansion. Wherever macro template is found in our source code, preprocessor replaces that macro template with macro expansion and the compiler compiles the code like normal source code.
Nested Ternary / Conditional Operator
Here we are using nested conditional operator. First we check if value of a is greater b and c, if true, value of a will be returned orelse we check if b is greater than c, if true, value of b will be returned orelse value of c will be returned.
In this video lets see how we can have multiple line of code inside macro expansion, by using preprocessor operator – macro continuation( \ ).
Where Is It Used?
While you’re writing complex logic inside macro expansion, you’ll need to break the line and write code in next line. In such cases macro continuation operator is very helpful. And the code looks much cleaner and clearer.
Video Tutorial: Macro Continuation (\) Preprocessor Operator: C Program
#include<stdio.h>
#define SQUR(x) \
printf("Square of %d is %d\n", x, (x * x));
int main()
{
SQUR(5);
return 0;
}
Output: Square of 5 is 25
Here we are writing the macro expansion in the next line, so we are making use of macro continuation preprocessor operator (\).
Source Code: Macro Continuation (\) Preprocessor Operator: C Program
#include<stdio.h>
#define COMPANY(x) switch(x) { \
case 1: printf("1. Oracle\n"); break; \
case 2: printf("2. IBM\n"); break; \
case 3: printf("3. Ripple\n"); break; \
default: printf("default. Banks\n"); \
}
int main()
{
COMPANY(3);
COMPANY(2);
COMPANY(50);
return 0;
}
Output: 3. Ripple 2. IBM default. Banks
Here we’ve multiple lines of code inside macro expansion. So at the end of each line we’ve written macro continuation symbol ( \ – backslash). Wherever you write the macro template, preprocessor will replace it with the macro expansion before execution.
Output: We’re inside init method We’re inside main method We’re inside end method
We could even use __attribute__((constructor)) and __attribute__((destructor)) in function definition, as shown in above source code.
Source Code: Suppressing warnings using #pragma Directive: C Program
#include<stdio.h>
#pragma warn -rvl /* No Return Value */#pragma warn -par /* Parameter Not Used */#pragma warn -rch /* Unreachable Code */
int main()
{
int count = 1;
printf("%d\n", count);
return 0;
count++;
}
int total()
{
printf("Sum of a and b is c\n");
}
void end(int x)
{
printf("We're inside end method\n");
}
Output: 1
Here function total has a return type of integer, but it doesn’t return any value from inside, so it must throw “no return value” warning. But that warning is suppressed by #pragma warn -rvl .
Function end takes a integer argument, but the value is nowhere used inside the function definition. Compiler should throw “Parameter Not Used” warning, but it’s suppressed by #pragma warn -par.
Inside main method, there is count++ after return. This code is never executed. So the compiler should throw “Unreachable Code” warning, which is suppressed by #pragma warn -rch.
Note: -(minus or subtraction) symbol before rvl, par and rch means compiler removes the warning. + sign indicated the warning will be shown in the editor after compilation of the program.
Also note that,
#pragma warn -rvl /* No Return Value */#pragma warn -par /* Parameter Not Used */#pragma warn -rch /* Unreachable Code */
doesn’t work on GCC compiler.
Important Note: The functions init() and end() should not receive any arguments and should not return any value, if we want to handle their invocation via #pragma.