Function definition in Macros in C - c

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.

Related

What does it means to have function calling procedure in place of initialization (for loop)?

#include<stdio.h>
int fun()
{
static int num=16;
return num--;
}
void main()
{
for(fun();fun();fun())
printf("%d\n", fun());
}
Here what is meaning of for(fun();fun();fun()) ?
All I know about for loop is that for(initialization;condition;change in variable ) and they(ini..,cond...,chang...) should contain (some variable with value, algebraic condition, ..).
Please correct me.
Your code is equivalent to:
#include <stdio.h>
int fun()
{
static int num=16;
return num--;
}
void main()
{
fun();
while (fun())
{
printf("%d\n", fun());
fun();
}
}
Is it clear now?

How to create a function from other 3 with the same signature in C

I'm working with C, and I'm trying to build a kind of "composite" function, by joining 2 functions with the same signature, and a third with almost the same signature but just one less argument. The functions should be executed in sequence, but the final function must have the same signature. You can think it as building a function with code blocks using same signature(I have it implemented in C++ with policy class, but I'm trying a C approach as the rest of the code is in C already).
I built some code very simple, just to explain my approach.
#include <stdio.h>
#include <stdlib.h>
typedef void simulFileProc(int a, int b);
typedef void simulRead(int a);
typedef struct compFunct{
simulFileProc* file1;
simulRead* read;
simulFileProc* file2;
} compFunct;
void realProc(int a, int b){
printf("call from realProc %d, %d\n",a,b);
}
void realRead(int a){
printf("call from read %d\n",a);
}
simulFileProc* join(int a, int b, compFunct* func){
void sf(int a, int b){
func->file1(a,b);
printf("intermediate line\n");
func->read(a);
func->file2(a,b);
}
return &sf;
}
int main() {
compFunct* c = malloc(sizeof(256));
c->file1 = &realProc;
c->read = &realRead;
c->file2 = &realProc;
int a=0;
int b=0;
simulFileProc* s = join(a,b,c);
s(4,3);
return 0;
}
It is working, but for some reason, just the first function print.
call from realProc 4, 3
intermediate line
If I comment the line "func->read(a);", I have a segmentation fault.
What is wrong ?? Is there a smarter way to do ?

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.

test1.c:7: error: syntax error before '{' token

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;
}

Use of Pointers in a separate function file

Working of Pointers
// swap.h
swap(int, int);
// swap.c
swap(int *i, int *j)
{
int k;
k=*i;
*i=*j;
*j=k;
}
// Practice.c
#include <stdio.h>
#include "swap.h"
main()
{
int i,j;
printf("\nEnter I = ");
scanf("%d",&i);
printf("\nEnter J = ");
scanf("%d",&j);
swap(&i, &j);
printf("\n I = %d",i);
printf("\n J = %d",j);
}
When I wrote this program in one file, the program was correctly executed. Now after I divided it into 2 parts, Practice.c that has main() function and swap.c that contains the swap(int *i, int *j) function, it did not go so well.
Here is the following process I used to execute the program.
gcc -c swap.c
gcc Practice.c swap.o -oPractice
As soon as I tried to execute the 2nd statement it did not compile and produced errors.
I used exactly the same process for executing another program, which had 3 files,
Practice.c { main() function }
Add.c { add() function }
Add.h { header file }
It did not have pointers.
Please tell me where I'm making the mistake.
In swap.h change
swap(int, int);
to
swap(int *, int *);
Your swap function takes integer pointers as parameters, but your declaration says to take integers. So compiler will give you errors.

Resources