function declaration inside main and also outside main in C - 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;
}

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

Avoiding stack overflow using a trampoline

The trampoline function in the program below works properly. I think the program below results in stack overflow because the functions thunk_f and thunk1 call each other indefinitely, resulting in the creation of new stack frames. However, I want to write a program that behaves more similarly to a nonterminating loop, as trampolines should prevent stack overflow.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
void trampoline(void *(*func)()) {
while (func) {
void *call = func();
func = (void *(*)())call;
}
}
void *thunk1(int *param);
void *thunk_f(int *param);
void *thunk1(int *param)
{
++*param;
trampoline(thunk_f(param));
return NULL;
}
void *thunk_f(int *param)
{
return thunk1(param);
}
int main(int argc, char **argv)
{
int a = 4;
trampoline(thunk1(&a));
printf("%d\n", a);
}
You are using the trampoline incorrectly: rather than letting it invoke your thunk_f function, you call it with the result of the thunk_f function.
As a result, you are getting a stack overflow. You can avoid the stack overflow (but not the infinite loop) by returning thunk_f instead of calling it:
void *thunk1(int *param)
{
++*param;
return thunk_f;
}
And calling trampoline in main correctly:
int main(int argc, char **argv)
{
int a = 4;
trampoline(thunk1, &a);
printf("%d\n", a);
}
And of course this requires that trampoline gets an additional argument, to pass the &a parameter on:
void trampoline(void *(*func)(int *), int *arg) {
while (func) {
void *call = func(arg);
func = (void *(*)())call;
}
}
This works — but as noted, it’s just an infinite loop without output. To see what’s happening, put the printf inside thunk1:
void *thunk1(int *param)
{
printf("%d\n", ++*param);
return thunk_f;
}
Lastly, I should probably note that this is invalid C, because it’s illegal to convert between a object pointer and a function pointer (always compile with pedantic warnings!). To make the code legal, wrap the function pointer into an object:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
struct f {
struct f (*p)(void *);
};
void trampoline(struct f f, void *args) {
while (f.p) {
f = (f.p)(args);
}
}
struct f thunk1(void *param);
struct f thunk_f(void *param);
struct f thunk1(void *param) {
printf("%d\n", ++*((int *) param));
return (struct f) {thunk_f};
}
struct f thunk_f(void *param) {
return thunk1(param);
}
int main() {
int a = 4;
trampoline((struct f) {thunk1}, &a);
}

dynamically allocated matrix gives seg fault when printed

this code allocates a matrix by means of a series of function calls, but when i print it, it return a segmentation fault error.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void mat_init(int** matx);
void pp_init(int** matx);
void p_init(int** matx);
void mat_fill(int** matx);
void mat_print(int** matx);
int main(void)
{
srand((unsigned)time(NULL));
int** matrix;
mat_init(matrix);
mat_print(matrix);
return 0;
}
void mat_init(int** matx)
{
pp_init(matx);
}
void pp_init(int** matx)
{
matx=malloc(4*sizeof(int*));
p_init(matx);
}
void p_init(int** matx)
{
for(int i=0;i<4;i++)
{
*(matx+i)=malloc(4*sizeof(int));
}
mat_fill(matx);
}
void mat_fill(int** matx)
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
*(*(matx+i)+j)=rand()%5;
}
}
//mat_print(matx);
}
void mat_print(int** matx)
{
printf("The matrix is:\n");
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
printf("%1i|",*(*(matx+i)+j));
}
puts("");
}
puts("");
}
note that this happens only if i print the matrix using mat_print() int the main, if i use it in the function mat_fill() it works correctly, showing that it's been properly initialized.
What's the problem?
Essentially what you're doing is this:
void foo(int a);
{
a = 6;
}
int main()
{
int a = 3;
foo(a);
printf("a = %d\n", a); // expecting this to print 6
return 0;
}
Everything in C is pass by value, so that means anytime a parameter is passed to a function, a local copy of it is made in that function, and its scope exists only in that function; there is no exception for pointers. If I have this code instead:
void foo (int* ap2)
{
// there are now 2 pointers in memory that point to the same thing (main's a), namely
// ap2 on this stack frame and ap1 in the previous stack frame.
*ap2 = 6;
// ap2 is local to this function, but it _points_ to the same thing as
// ap1, so when we dereference it, changes to _what it points to_ are seen
// outside of this function. But once we return from this function, ap2
// ceases to exist
}
int main()
{
int a = 3;
int* ap1 = &a;
foo(ap1);
printf("a = %d\n", a); // now this prints 6
return 0;
}
If you want to manipulate main's matx in a function, then you need to pass a pointer to it and dereference it in that function in order to modify what it points to.
void foo (int*** matxp)
{
// matxp now points to matx in main
// dereference it here
*matxp = malloc(4 * sizeof(int*));
}
int main()
{
int** matx;
foo(&matx); // pass the address of matx here, which is an int*** type
....
// don't forget to clean up everything
return 0;
}
But as I said in the comments, I've rarely/never seen 3 star pointers. Instead you could just return the value
int** foo()
{
matxp = malloc(4 * sizeof(int*));
return matxp; // this will return NULL if malloc failed
}
int main()
{
int** matx = foo();
....
// do work, cleanup
return 0;
}
You need to do this:
int** mat_init(int** matx);
int** pp_init(int** matx);
int main(void)
{
matrix=mat_init(matrix);
}
int** mat_init(int** matx)
{
return pp_init(matx);
}
int** pp_init(int** matx)
{
matx=malloc(4*sizeof(int*));
p_init(matx);
return matx;
}
I omitted some lines that I didn't change. Another option is this:
void mat_init(int*** matx);
void pp_init(int*** matx);
int main(void)
{
mat_init(&matrix);
}
void mat_init(int*** matx)
{
pp_init(matx);
}
void pp_init(int*** matx)
{
*matx=malloc(4*sizeof(int*));
p_init(*matx);
}
Another thing: You're using the value 4 on a lot of places. That's dangerous. use a constant instead.
#define MAT_SIZE 4
void mat_fill(int** matx) {
for(int i=0;i<MAT_SIZE;i++) {
for(int j=0;j<MAT_SIZE;j++)

How function declarations work?

#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

Resources