I am trying to create a multiline macro and i am facing this error.
#include<stdio.h>
#define call(a) \
if ((a)>0) \
printf("printing a %d:"a)
int main
{
int a =10;
call(a);
return 0;
}
int main needs to be written as int main().
Also, there should be no whitespace after the final \ of a multi-line macro. That can cause spurious compiler errors.
C function declaration requires parentheses, with or without parameters.
int f { ... } // incorrect
int f() { ... } // correct
Missing "," in prinf() function befor variable "a".
#include<stdio.h>
#define call(a)\
if ((a)>0)\
printf("printing a %d:",a)
int main()
{
int a =10;
call(a);
return 0;
}
Related
I wanted to make a custom array in C like std::array in C++. However the following code doesn't work.
array.h:
#ifndef CUSTOM_ARRAY
#define CUSTOM_ARRAY
#define array(T, name, n_elements) do { \
T name [(n_elements)]; \
} while(0)
#endif
main.c:
#include "array.h"
#include <stdio.h>
int main()
{
array(int, array_name, 5);
size_t size_of_array = sizeof(array_name) / sizeof(array_name[0]);
for (int i = 0; i < size_of_array; i++) {
array_name[i] = i;
printf("%d\n", array_name[i]);
}
return 0;
}
It displays the following errors message:
main.c: In function 'main': main.c:10:35: error: 'array_name' undeclared (first use in this function) 10 | size_t size_of_array = sizeof(array_name) / sizeof(array_name[0]); | ^~~~~~~~~~ main.c:10:35: note: each undeclared identifier is reported only once for each function it appears in
But in main.c, doesn't the array in the macro expand into:
int array_name[5];
You are limiting the scope of the array to that one statement.
Replace
#define array(T, name, n_elements) do { \
T name [(n_elements)]; \
} while(0)
with
#define array( T, name, n_elements ) T name[ n_elements ]
This code throws out an error saying that "code undelcared."
#include<stdio.h>
#define MAIN() c##o##d##e
int main()
{
MAIN();
printf("C program");
return 0;
}
int code()
{
printf("C is life");
}
Whereas, this code runs smoothly.
#include<stdio.h>
#define MAIN() m##a##i##n
int main()
{
MAIN();
printf("C program");
return 0;
}
int code()
{
printf("C is life");
}
Output:
C program
This code also runs smoothly.
#include <stdio.h>
#define macro(n, a, i, m) m##a##i##n
#define MAIN macro(n, a, i, m)
int MAIN()
{
printf("C is life");
return 0;
}
Output:
C is life
In the first code, why doesn't the code work as like main? I don't know what is the process after the concatenation 'main' is completed by the macro. Kindly explain the process behind these codes, in simple terms. Thanks in advance.
I also tried by defining the code function.
#include<stdio.h>
#define MAIN() c##o##d##e
int code(void);
int main()
{
MAIN();
printf("C program");
return 0;
}
int code(void)
{
printf("C is life\n");
return 0;
}
Output:
C program
So, defining a function should not be the problem. My question is, what happens after concatenation? Thanks in advance.
In C (since the C99 standard) you need to declare all functions before you use them.
In the first example you haven't declared the code function before you attempt to use it. You solve it by adding a function prototype:
// Declare the function, also known as a function prototype
void code(void);
int main(void)
{
// ...
}
// Define the function
void code(void)
{
// ...
}
The second example works because you use main which is already declared at that point. If a function haven't been declared before, the definition also declares the function.
Also note that your macro after expansion doesn't actually call the code (or the main) function. This is good, since calling main recursively (directly or indirectly) is generally bad.
In C, you have to define the prototype of your function int code () before any calls :
int code (void);
The function main is declared in assembly code, this is why your second version compiles et runs correctly.
If you want to avoid this error please add -Wmissing-prototypes compilation flag in order to let the compiler checks for you if your function has a prototype.
The problem is that code() function is not yet declared when main() is compiled.
Either move code() before main():
#include<stdio.h>
#define MAIN() c##o##d##e
int code()
{
printf("C is life");
}
int main()
{
MAIN();
printf("C program");
return 0;
}
Or forward declare code():
#include<stdio.h>
#define MAIN() c##o##d##e
int code();
int main()
{
MAIN();
printf("C program");
return 0;
}
int code()
{
printf("C is life");
}
Just remember macros are replaced at preprocessor stage itself. In C, every function needs to be prototyped before using/calling it so that compiler knows in advance about it's arguments and return type to avoid conflicts.
Case 1 :- when below code blocks executes, macro name MAIN() got replaced with code.
#define MAIN() c##o##d##e
int main(){
MAIN();
printf("C program");
return 0;
}
int code(){
printf("C is life");
}
And it looks like below after pre-processor stage
int main(){
code; /* errorenous statement */
printf("C program");
return 0;
}
int code(){
printf("C is life");
}
observe the line code; in above code block, it cause the compilation error. When you run above code like gcc -Wall -Wstrict-prototypes -Werror test.c where it will convert warning into error.
error: ‘code’ undeclared (first use in this function) #define MAIN()
c##o##d##e
^
to solve this, declare the code() like before #define
int code(void); /* declaration */
There is one more warning converted into error
error: statement with no effect [-Werror=unused-value] #define MAIN()
c##o##d##e
Because after macro replacement it looks like code; and here compiler rightly complaining above statement with no effect. So to avoid this
change the macro name from MAIN() to MAIN. for e.g
#define MAIN c##o##d##e
Correct version of case-1 code
#include<stdio.h>
int code(void);
#define MAIN c##o##d##e
int main(void){
MAIN();
printf("C program");
return 0;
}
int code(void){
printf("C is life");
return 0;
}
And it produces output as
C is lifeC program
Case 2 :- when below code executes, macro name MAIN() gets replaced with main
#define MAIN() m##a##i##n
int main(){
MAIN();
printf("C program");
return 0;
}
int code(){
printf("C is life");
}
And it looks like at preprocessor stage
int main(){
main; /* it causes error */
printf("C program");
return 0;
}
int code(){
printf("C is life");
}
Case 3 :- when below code blocks executes, macro name MAIN() got replaced with code & here you declared the code() also.
#define MAIN() c##o##d##e
int code(void);
int main() {
MAIN();
printf("C program");
return 0;
}
int code(void) {
printf("C is life\n");
return 0;
}
And it looks like below after pre-processor stage
int code(void);
int main() {
code;/* error causing statement */
printf("C program");
return 0;
}
int code(void) {
printf("C is life\n");
return 0;
}
Suggest you to compile any C code with
gcc -Wall -Wstrict-prototypes -Werror test.c
so by converting warning to error you will learn more.
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.
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;
}
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