How function declarations work? - c

#include <stdio.h>
void bar();
int main()
{
void foo();
printf("1 ");
foo();
bar();
}
void foo()
{
printf("2 ");
}
void bar()
{
foo();
}
Output:
1 2 2
Shouldn't the function foo() be visible only inside main() ?
But this is not the case.
Are function declaration in C always to every functions?

let me explain commenting the original code you pasted :)
#include <stdio.h>
void bar(); //so, we declared bar here, thus it will be called successfully later
int main()
{
void foo(); //we declared foo here, thus the foo two statements below also can be called
printf("1 ");
foo(); //this works because the void foo(); some lines above
bar(); //this works because of bar() outside the main()
}
void foo() //here foo is defined
{
printf("2 ");
}
void bar() //here bar is defined
{
foo(); //this works because foo was declared previously
}
Indeed, you are both right, and wrong, right in the sense that the first declaration of foo() goes out of scope after main ends. Wrong in the sense that the linker would confuse stuff, the linker, that decides what function call calls what, can find the foo outside the main and figure that is the same foo declared inside the main.
That said, you should not declare functions inside other functions...
Also here is a better proof of what you want to know:
I tried to compile this:
#include <stdio.h>
void bar();
void bar()
{
void foo();
foo();
}
int main()
{
printf("1 ");
foo(); //line 18
bar();
}
void foo()
{
printf("2 ");
}
It gave me this error: prog.c:18:9: error: implicit declaration of function ‘foo’ [-Werror=implicit-function-declaration]
This is because the foo() inside bar() is valid, but the foo() on main is not, because although foo() is declared before main, it is still valid only inside bar()

foo() is visible in bar() because it has been defined before.
If you implement foo() after bar() there will be a compiler error
#include <stdio.h>
void bar();
int main()
{
void foo();
printf("1 ");
foo();
bar();
}
void bar()
{
foo();
}
void foo()
{
printf("2 ");
}
brings:
'foo': identifier not found

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?

Why can't I pass void and a parameter to the function in C?

#include <stdio.h>
void fun();
int main(void) {
fun(fun());
return 0;
}
void fun()
{
printf("function is called");
}
The return type of function fun is void. So the below statement should be valid right!
fun(fun())
But the compiler raises compilation error as error: argument type 'void' is incomplete. Cannot understand what the error means?
I think you want something like this:
#include <stdio.h>
int fun(int arg); // function takes one argument
int main(void) {
fun(fun(1)); // use one argument when calling fun
return 0;
}
int fun(int arg)
{
printf("function is called\n");
return 0;
}

Function definition in Macros in 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.

why func() and func(void) are different [duplicate]

This question already has answers here:
in c: func(void) vs. func() [duplicate]
(2 answers)
Closed 9 years ago.
I have a function, can write in 2 ways.
void function(void) {
// operations....
}
and
void function() {
// operations......
}
Both functions are of same prototype. Why we have to mention void as argument at function definition?
No, both have different prototypes.
Compile the below programs you will understand.
void function1(void)
{
printf("In function1\n");
}
void function2()
{
printf("In function2\n");
}
int main()
{
function1();
function2(100); //Won't produce any error
return 0;
}
Program 2:
#include <stdio.h>
void function1(void)
{
printf("In function1\n");
}
void function2()
{
printf("In function2\n");
}
int main()
{
function1(100); //produces an error
function2();
return 0;
}
The correct way to say "no parameters" in C and C++ is
void function(void);
But when we write
void function();
It means a little different way in C and C++! It means "could take any number of parameters of unknown types", and in C++ it means the same as function(void).

function declaration inside main and also outside main in C

The first program compiled properly.second gave error saying too few argument for foo...
is global declaration ignored by the compiler in both programs?
first program:
#include<stdio.h>
void foo();
int main()
{
void foo(int);
foo(1);
return 0;
}
void foo(int i)
{
printf("2 ");
}
void f()
{
foo(1);
}
second program:
void foo();
int main()
{
void foo(int);
foo();
return 0;
}
void foo()
{
printf("2 ");
}
void f()
{
foo();
}
The inner declaration hides declarations at the global scope. The second program fails because the declaration void foo(int); hides the global declaration void foo();; so when you say foo within main you are referring to the one taking an int as argument.
I see that you investigate the specific behavior of inner declaration but why not:
#include<stdio.h>
void foo(int);
int main()
{
foo(1);
return 0;
}
void foo(int i)
{
printf("2 ");
}
void f()
{
foo(1);
}
or even:
#include<stdio.h>
void foo(int i)
{
printf("2 ");
}
void f()
{
foo(1);
}
int main()
{
foo(1);
return 0;
}

Resources