In script languages, such as Perl and Python, I can change function in run-time. I can do something in C by changing the pointer to a function?
Something like:
void fun1() {
printf("fun1\n");
}
void fun2() {
printf("fun2\n");
}
int main() {
fun1 = &fun2;
fun1(); // print "fun2"
return 0;
}
No. You can't do that.
You can regard fun1 as a placeholder for the fixed entry point of that function.
The semantic you are looking for is that from fun1=&fun2; point on every call to fun1 causes fun2 to be called.
fun1 is a value not a variable. In the same way in the statement int x=1; x is a variable and 1 is a value.
Your code makes no more sense than thinking 1=2; will compile and from that point on x=x+1; will result in x being incremented by 2.
Just because fun1 is an identifier doesn't mean it's a variable let alone assignable.
Yes; You can and this is the simple program which will help you in understanding this
#include <stdio.h>
void fun1() {
printf("fun1\n");
}
void fun2() {
printf("fun2\n");
}
int main() {
void (*fun)() = &fun1;
fun(); // print "fun1"
fun = &fun2;
fun(); // print "fun2"
return 0;
}
Output
➤ ./a.exe
fun1
fun2
You can't change fun1, but you can declare a function pointer (not a function, only a pointer to a function).
void (*fun)();
fun = fun1;
fun(); /* calls fun1 */
fun = fun2;
fun(); /* calls fun2 */
As you might have noticed it is not necessary to take the address of fun1/fun2 explicitely, you can omit the address-of operator '&'.
Related
This question already has answers here:
Error "initializer element is not constant" when trying to initialize variable with const
(8 answers)
Closed 2 years ago.
Hi i have a test code for calling malloc as below:
#include <stdio.h>
#include <stdlib.h>
int *p;// = (int*)malloc(sizeof(int));
int main() {
//...
}
Of course this code will be fail when compile with the error: initializer element is not constant and i have referenced this question: Malloc function (dynamic memory allocation) resulting in an error when it is used globally. They said that we have to use malloc() in side a function. But if i change my code to:
#include <stdio.h>
#include <stdlib.h>
int *p;
static int inline test_inline(int *x) {
printf("in inline function \n");
x = (int*)malloc(sizeof(int));
return x;
}
test_inline(p);
int main(){
//...
}
As the definition of inline function: "Inline Function are those function whose definitions are small and be substituted at the place where its function call is happened. Function substitution is totally compiler choice." So this mean we can substitute the inline function test_inline in above example with the code inside it and it means we have call malloc() in global ? Question 1: is this wrong about inline or malloc() ?
Question 2: In the link i give about malloc function dynamic there is an answer said that "Not only malloc, u can't call any function as you have called here. you can only declare function as global or local there" but i see that we still can call function in global and in global we can initialization not only declaration as below:
#include <stdio.h>
#include <stdlib.h>
int b;
b = 1;
int test() {
printf("hello");
}
test();
int main() {
//...
}
So this mean in the global we still can declaration and initialization and call function. But when we compile the above code it has a warning that warning: data definition has no type or storage class So why we have this warning with variable b ? I do not see any thing which inconsequential here. And with the line test(); i have call a function outside main(), i know this make no sense because we never run test() but i have no problem, stil build success. So back to question 1 about the malloc(), i think with the answer that "we can not call a function in global or can not initialize", i think it is not true. Is there any explain more reasonable?
Please refer to the comments.
#include <stdio.h>
#include <stdlib.h>
int b;
b = 1; //this is only allowed, because the previous line is a tentative definition. [1]
int test() {
printf("hello");
}
test(); // this is taken as a function declaration, not a function call [2]
int main() {
//...
}
Case [1]:
Change you code to
int b = 5; // not a tentative defintion.
b = 1; // this assignment is not valid in file scope.
you'll see an error.
Case [2]:
If the signature of the function differs, you'll again see an error. Example: try the below:
float test( int x ) {
printf("hello");
return 0.5;
} //return changed to float, accepts an int as paramater.
test(); //defaults to int and no parameter - conflict!!
this will produce the error for conflicting types.
So, bottom line, no assignment, function call - all in all, no code that needs to execute at runtime, can be put into file scope. The reason behind that being, unless it's contained in a function that's called from main(), there's no way to know when / how to execute it.
You're not calling functions "globally".
Taking your example:
#include <stdio.h>
#include <stdlib.h>
int b;
b = 1;
int test() {
printf("hello");
}
test();
int main() {
//...
}
In C types default to int.
So the lines
int b;
b = 1;
are basically
int b;
int b = 1;
and the lines
int test() {
printf("hello");
}
test();
are just
int test() {
printf("hello");
}
int test(); // -> this is just a matching declaration
Have a look at:
https://godbolt.org/z/3UMQAr
(try changing int test() { ... to char test() { ... and you get a compiler error telling you that those types don't match)
That said, you can't call functions there. Functions are called at runtime by your program (especially malloc, which is asking your OS to allocate memory for you). I'm not a C expert here but as far as I know C doesn't have constexpr functions, which would be the only "exception".
See: Compile-Time Function Execution
Question 1: is this wrong about inline or malloc()
kind of: malloc does have to be called in a function, but the variable it works on can be declared global. i.e. int *pointer = NULL;//global scope
then pointer = malloc(someByteCount);//called within function. Now, pointer is still global, but also has a memory address pointing to someByteCount bytes of memory.
Question 2: In C, all functions are defined on the same level of a .c file, just like main(void){...return 0}, but all functions (except main(void)) must be called within the {...} of other functions, so in short, functions cannot be called from global space.
Illustration for Q2:
//prototypes
void func1(void);
void func2(void);
void func3(void);
int main(){
int val = test_inline(p);//...
}
int main(void)
{
//legal
func1();
func2();
func3();
return 0;
}
//not legal
func1();
func2();
func3();
//definitions
void func1(void)
{
return 0;
}
void func2(void)
{
return 0;
}
void func3(void)
{
return 0;
}
Errors in syntax of your example (see comments):
int *p = NULL;//initialize before use
static int inline test_inline(int *x) {
printf("in inline function \n");
x = (int*)malloc(sizeof(int));
printf("%p\n", x);
return 0;
//return x;//function returns int, not int *
}
//... test_inline(p);//must be called in a function
int main(void){
int val = test_inline(p);//function declaration returns int, not pointer
return 0;
}
This code compiles, and runs, but as noted in comments, usefulness may be lacking.
Question 1: is this wrong about inline or malloc() ?
Neither. Your understanding of inline is incorrect. The function call may be replaced with an inline expansion of the function definition. First, let's fix the function definition because the return type int doesn't match the type of what you're actually returning:
static inline int *test_inline( int *x )
{
printf( "in inline function\n" );
x = malloc( sizeof *x );
return x; // x has type int *, so the return type of the function needs to be int *
}
If you call this function like so:
int main( void )
{
int *foo = test_inline( foo );
...
}
what the compiler may do is substitute the function call with the assembly language equivalent of the following:
int main( void )
{
int *foo;
do
{
printf( "in inline function\n" );
int *x = malloc( sizeof *x );
foo = x;
} while( 0 );
...
}
Nothing's happening "globally" here. The substitution is at the point of execution (within the body of the main function), not at the point of definition.
Question 2: In the link i give about malloc function dynamic there is an answer said that "Not only malloc, u can't call any function as you have called here. you can only declare function as global or local there" but i see that we still can call function in global and in global we can initialization not only declaration as below:
In the code
int test() {
printf("hello");
}
test();
the line test(); is not a function call - it's a (redundant and unnecessary) declaration. It does not execute the function.
Here are some excerpts from the language definition to clarify some of this:
6.2.4 Storage durations of objects
...
3 An object whose identifier is declared without the storage-class specifier
_Thread_local, and either with external or internal linkage or with the storage-class
specifier static, has static storage duration. Its lifetime is the entire execution of the
program and its stored value is initialized only once, prior to program startup.
Bold added. Any variable declared outside the body of a function (such as p in your first code snippet) has static storage duration. Since such objects are initialized before runtime, they cannot be initialized with a runtime value (such as the result of a function call).
6.7.4 Function specifiers
...
6 A function declared with an inline function specifier is an inline function. Making a
function an inline function suggests that calls to the function be as fast as possible.138)
The extent to which such suggestions are effective is implementation-defined.139)
138) By using, for example, an alternative to the usual function call mechanism, such as ‘‘inline
substitution’’. Inline substitution is not textual substitution, nor does it create a new function.
Therefore, for example, the expansion of a macro used within the body of the function uses the
definition it had at the point the function body appears, and not where the function is called; and
identifiers refer to the declarations in scope where the body occurs. Likewise, the function has a
single address, regardless of the number of inline definitions that occur in addition to the external
definition.
139) For example, an implementation might never perform inline substitution, or might only perform inline
substitutions to calls in the scope of an inline declaration
All this means is that the inlined code behaves like it was still a single function definition, even if it's expanded in multiple places throughout the program.
I am calling one function in which values are printed, but when void is added before the call, the function is not giving correct (or any) output.
I tried various methods
#include <stdio.h>
void func1();
void func2();
void func1()
{
printf("Inside func1()\n");
}
void func2()
{
printf("Inside func2()\n");
}
int main()
{
void func1();
void func2();
printf("Inside main()\n");
return 0;
}
Output is :-
Inside main
When void is removed before calling func1 and func2, the output is changed.
#include <stdio.h>
void func1();
void func2();
void func1()
{
printf("Inside func1()\n");
}
void func2()
{
printf("Inside func2()\n");
}
int main()
{
func1();
func2();
printf("Inside main()\n");
return 0;
}
Output is :-
Inside func1
Inside func2
Inside main
Can anyone explain how void is affecting desired output?
The statement void func1(); within main is a function declaration. This is a no-op at runtime.
func1(); actually calls the function.
It's how the language grammar works, that's all. It's rather clever if you think about it.
In this case, void func1(); is not a call to the function, it just means: somewhere there may be a function with this signature, I want to use it even if it is not declared forward. Usually we call this a function declaration and we don't use it inside main but at the beginning of the file.
A function declaration is the action to tells the compiler about a function's name, return type, and parameters.
eg:-void func1();
A function definition provides the actual body of the function.
eg:-
void func1()
{
printf("Inside func1()\n");
}
To call a function, you simply need to pass the required parameters along with the function name, and if the function returns a value, then you can store the returned value.
eg:-func1();
A declaration always begins with a type name. When you write
int func();
you are declaring to the compiler that you have a function that takes an unspecified number of parameters and returns int (so the compiler knows about it).
When you write
func();
you are telling the compiler to execute function func(); and discard its result, in a normal execution statement.
Always you have a C statement beginning with a type identifier
, that's not to be executed, but to inform the compiler of the existence of such thing (to declare it)
In your example, you changed two declarations at the beginning of main() into to execution statements. As such, the compiler generated code to execute those, resulting in the output you got on execution.
I am making a program in C in which I am trying to use the values of local variable in other function. Lets say I have two function foo1 foo2.
int foo1()
{
int a=2,b=3,c;
c=a+b;
return c;
}
int foo2(int c)
{
printf("Value of C is %d",c);
}
is this method correct, if not what else is the way to use values of local variable in other function?
first of all, this two functions foo1() and foo2() are not related...
and local variables have block scope only.
If you want to use them in other functions make them global or use pass by value and pass by reference methods to pass the variables from one function to others...
You cannot, and you should not use local variables from other functions directly.
But in your case you are lucky: the value from foo1() you are interested in is returned to the caller.
This way you can use it as you like:
...
int value = foo1();
foo2(value);
...
or even shorter:
...
foo2(foo1());
...
You can do this -
int foo1()
{
int a=2,b=3,c;
c=a+b;
return c;
}
// c will be passed to the function and printed
int foo2(c)
{
printf("Value of C is %d",c);
}
// get the result of foo1()
int val = foo1();
// call foo2() with the result of foo1()
foo2(val);
One way is to make c variable global so that every function can use it.
other way is to call this returning function in foo2() so that the returned value can be printed.
one way:
int foo1(){
int a=2,int b=3;
int c=a+b;
return c;
}
int foo2(){
printf("value of c = %d",foo1()); //returned value of function foo1() used
}
other way is :
int c=0; //defined global
void foo1()
{
int a=2,int b=3;
c=a+b;
}
void foo2()
{
printf("value of c = %d",c);
}
I know that If a function has no argument & only return type (say int), then I can change my int variable by assigning the function to my variable as below,
main()
{
int var_name;
var_name = func();
printf("My variable value is updated as : %d", a);
}
func()
{ return 100; }
Also I know that If I have my function's return type as void, with no arguments, then I can only print the value inside the function itself and cannot return anything in turn.
But, my doubt is, is there anything else that I can do to update my var_name by calling a function with no arguments & no return type ?
ie., void func(void); by using something like pointer concepts ??
I could not able to find the exact answer for the same by my searches among so many websites.. I will be very grateful if someone can help me out finding whether I can do it by this way or not,.
Thanks,.
It is possible to modify a local variable in main, from a function with no arguments and no return value, if there's a global pointer to it:
#include <stdio.h>
int *p;
void func() {
*p = 6;
}
int main() {
int a = 5;
p = &a;
func();
printf("a = %d\n", a); // prints: a = 6
return 0;
}
There's no good way to do that. If you want the function to modify a local variable, you should probably change the function so it either returns a value that you can assign to the variable, or takes the variable's address as an argument.
But if you don't mind writing some ugly code, you can define a global (file-scope) pointer variable, assign the local variable's address to the global pointer, and then use that to modify the variable inside the function.
An example:
#include <stdio.h>
int *global_pointer;
void func(void) {
*global_pointer = 42;
}
int main(void) {
int local_variable = 0;
global_pointer = &local_variable;
func();
printf("local_variable = %d\n", local_variable);
}
It's very easy to shoot yourself in the foot his way. For example, if you refer to the pointer after the calling function has terminated (and the local variable no longer exists), you'll have undefined behavior.
This technique can actually be useful if you need to make a quick temporary change in a body of code in which you can't make major interface changes. Just don't do it in code that will be maintained by anyone else -- and wash your hands afterward.
You can have global variable
int var_name;
void func();
int main()
{
func();
printf("%d\n",var_name);
}
void func()
{
var_name = 20;
}
But if your variable is local to main() then this can't be done.
There are two ways to modify the value of var_name.
Make changes in the calling function and return the value.( which you have already shown)
Pass the address of the var_name to the function and have pointer as arguement in the func(int *p) and modify the value inside the func()
Thats it!! No other way this can be done.
In C, suppose var1 is a variable in foo1() and foo2() wants to access var1, however, foo1() doesn't call foo2(), so we can't pass it by parameter. At the same time, only foo1() and foo2() will access it, so I wouldn't like to declare it as global variable. It will be similar with the "friend semantics" in c++, is there any way to implement this in C?
void foo1() {
...
var1;
....
}
void foo2() {
...
how to access var1?
...
}
you pass the variable to both functions.... in general functions shouldn't hold state.
quickly you find passing variables is not so nice and becomes fragile, so instead, you pass structs.... then functions start working on the state of structs.
typedef struct
{
int var1;
} blah_t;
void foo1(blah_t* b)
{
b->var1=0;
}
void foo2(blah_t* b)
{
b->var1++;
}
this is the very simplistic seed idea behind doing OO C.
You need to declare var1 outside the scope of the functions and then send it as a parameter to both. Alternatively, declare it as a global variable.
by reference is one way: (in this example the memory for i is local to caller())
void caller()
{
int i = 5;
foo(&i);
bar(&i);
printf("\n final i is %d",i);
}
void foo(int *i)
{
printf("%d",*i);
*i += 5;
}
void bar (int *i)
{
printf("%d",*i);
*i += 5;
}
global: (usually considered horrible i would have a name more like GLOBAL_I or something)
int i = 0;
void caller()
{
i=5;
foo();
bar();
printf("\n final i is %d",i);
}
void foo()
{
printf("%d",i);
i += 5;
}
void bar (int i)
{
printf("%d",i);
i += 5;
}
Regarding similar with the "friend semantics" in c++. C does not have the same capability.
Regarding so we can't pass it by parameter
The only option in C for accessing a variable from function to function without passing as a function parameter is to use some type of global scope variable.
In the event void foo1() and void foo2() exist in different C modules...
but you still want to be able to access the same variable, and ensure its value is the same at all times, in all places within your project, then consider using extern scope:
Within a header file that is common to both (multiple) modules, a project scope global can be implemented as follows.
file.h
void foo1(void);
void foo2(void);
extern int var1;
file1.c
#include "file.h"
int var1 = 5; //in only 1 module, declare and initialize the
//extern defined in the common header -file.h-
int main(void)
{
printf("value of var1 is %d\n", var1);//original value of var1
foo1();
printf("value of var1 is %d\n", var1);//var1 modified by foo1()
foo2();
printf("value of var1 is %d\n", var1);//var1 modified by foo2()
return 0;
}
void foo1(void)
{
var1 = 15;//Now that the project global variable
//has already been declared and defined, it can simply
//be used, in this file...
}
file2.c
#include "file.h"
void foo2(void)
{
var1 = 20;... and in this one
}
No. The variable only exists on the function stack while foo1() is running. The stack will vanish when leaving the function. You could make the variable static to keep it alive, but then you can't access it from the outside either without hacks.
This answer is inspired by the 'Module' concept, found in many other languages, which can be approximated using gcc's nested functions. Variable var1 is within scope for both foo1() and foo2(), but is out of scope for everything else. The solution uses neither global vars nor parameters.
void foo(int fn)
{
static int var1;
void fn1(void)
{
var1 = 15;
}
void fn2(void)
{
var1 = 20;
}
(fn == 1)? fn1(): fn2();
printf("Value of var1 is now %d\n", var1);
}
void foo1(void){foo(1);}
void foo2(void){foo(2);}
int main (void)
{
foo1();
// Expected stdout: Value of var1 is now 15
foo2();
// Expected stdout: Value of var1 is now 20
}