c, pointers, and argument list to printf. confused - c

Can someone explain why the value of the variable test isn't changed when I run the short code snippet below?
#include <stdio.h>
int f1(char * foo) {
*foo = 'a';
return 0;
}
void main(void) {
char test = 'n';
printf("f1(&test)=%d. test's new value? : %c", f1(&test), test);
}
I know I'm probably missing something really simple. I just don't understand why test isn't changed in f1() because I'm passing it's address in, right? Why does it matter that the actual function call happens in the list of arguments to printf() ?
If I take the call to f1() out of the printf argument list like so:
#include <stdio.h>
int f1(char * foo) {
*foo = 'a';
return 0;
}
void main(void) {
char test='n';
int i;
i = f1(&test);
printf("f1(&test)=%d. test's new value? : %c", i, test);
}
things work as expected.
thanks in advance.

The order in which the arguments to a function call are evaluated is unspecified. Put another way, you can't tell for sure when f1(&test) will be evaluated.
So in your example, perhaps f1(&test) is evaluated after test: slightly counter-intuitively, you don't get to see the side effects of that invocation. But if you print test again after the call, you will indeed see them.
Bottom line, just be careful with function that have side-effects and you should be set.

There is no set order in which function parameters are evaluated. You're banking on the idea that the arguments are evaluated left to right, which can't be assumed.

Just change where you make your function call
#include <stdio.h>
int f1 (char* foo) {
*foo='a';
return 0;
}
int main(void)
{
char test='n';
f1(&test);
printf("test=%c\n", test);
return 0;
}

Related

What happens when you call a function with return value without assigning it to any variable?

#include <stdio.h>
#include <stdlib.h>
int f(int x) {
return x;
}
int main ( int argc,char * argv[]) {
int a=4;
f(a);
printf("PASSED!\n");
return 0;
}
What happens when you call f(a) without assigning it to anything?
What happens when you call a function with return value without assigning it to any variable?
The return value of a function need not be used or assigned. It is ignored (usually quietly).
The function still executes and its side effects still occur.
Consider the 3 functions: int scanf(), int f(), and int printf(), their return values are all ignored yet the functions were still executed.
int a=4;
scanf("%d", &a);
f(a);
printf("PASSED!\n");
It is not good to ignore return values in robust code, especially scanf().
As commented by #Olaf, a warning may be enabled by some compilers.
Explicit ignoring the result of a function is sometime denoted with (void) to quiet that warning.
(void) f(a);
Using your example, we can look at how it evaluates line by line. Starting in main.
int a=4;
We now have a variable a with the value 4.
f(a);
So now the function f is called with a, which has a value of 4. So in the function f, the first parameter is named x and it just returns that parameter x.
So the evaluation of
f(a);
is just
4;
And a program like this compiles and runs perfectly fine.
int main(int argv, char *argv[]) {
1 + 1;
return 0;
}
What happens when you call f(a) without assigning it to anything?
--> Nothing at all.
What happens when you call a function (which has return value) without assigning it to anything?
-->The function will be executed, either make no sense like your case or make a lot of senses like modifying a static variable or a global variable. The return value will be ignored.
The return value will normally be stored in a register and will not fade.
It will be overwritten when the register is needed by the compiler.
If the function is inline it may be detected by the compiler that the value isn't used and ignore the value from being computed at all.

why does the compiler give a warning for unused function?

I have just written a sample program to understand the working of functions in C. I declared a function in C and call it during my programs execution. However my compiler gives me a warning saying unused function. My code looks like this :
#include <stdlib.h>
#include <stdio.h>
int test_function(x);
int main(){
int x;
char letter[] ={"HAAA"};
char cmpre[] = {"AHD"};
int value;
for(int i=0; i<4;i++)
{
if(letter[i] == cmpre[i])
{
x=0;
}
}
int test_function(x)
{
if (x==0)
{
printf("the letters are the same");
}
return value;
}
printf("To check if the letters are the same go to the function");
test_function(x);
return 0;
}
The program seems to execute fine but I get a warning in the fourth line where I declared the function in the start of the program. The warning is :
Multiple markers at this line
- parameter names (without types) in function declaration [enabled by
default]
- Unused declaration of function 'test_function'
I think the way I am calling my function is not right. Could somebody please help me. Thnak you in advance.
Disclaimer: nested functions are non-standard C and I only know (of) the GNU extension for this. As such anything I claim here may well be untrue in another implementation. My recommendation is that you just don't use them at all.
Your nested test_function is shadowing the global declaration. So the test_function you declared above main is never called, because the call inside main refers to the nested function. Hence, you get a warning.
You should declare int test_function outside of main
for example.
int test_function(int x)
and then call the function in main.
value = test_function(x)
This is what your code should look like:
#include <stdlib.h>
#include <stdio.h>
int test_function(x)
{
int value = 0;
if (x==0)
{
printf("the letters are the same");
}
return value;
}
int main(){
int x = 0;
char letter[] ={"HAAA"};
char cmpre[] = {"AHD"};
int value = 0; // unused
for(int i=0; i<4;i++)
{
if(letter[i] == cmpre[i])
{
x=0;
}
}
printf("To check if the letters are the same go to the function");
test_function(x);
return 0;
}
Note that if you dont need a return value you could make the function void.
And initialize your variables. You may search hours to find such a error

how can you check if a void function ran successfully with printf?

A friend told me there is a way to check with printf without modifying the original void function.
But I can't see how you can do it.
#include<stdio.h>
void test()
{
int a = 1;
int b = a;
}
main()
{
printf("%d",test());
}
I kept getting
error: invalid use of void expression
Is there a way to do it?
I see from your edit that you want to do this without modifying the function. You can employ the comma operator to make the function call in a printf:
#include <stdio.h>
void test()
{
int a = 1;
int b = a;
}
main()
{
printf("%d\n", (test(), 0));
// or even this, to be more explicit:
printf("%s\n", (test(), "test() was called."));
}
The comma operator evaluates the first operand - in this case your function call - and discards the result, then evaluates the second operand and the result is the result of the entire expression.
An example would be to pass memory pointer into the void function and fill it with data you need to see if your void function worked.
void
test_funtion(bool *answer)
{
answer = false;
// do stuff
if(error happens)
return;
answer = true;
return;
}
I don't see how you would use printf to let the program know.
Only way you would use printf for visual logging for yourself, but not the machine.

Global variable showing abrupt behavior

here is my code.
#include <stdio.h>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define SZA(a) (sizeof(a)/sizeof(a[0]))
int anish=0; // global variable showing abrupt behaviour
int a[]={0,1,5,8,9,10,17,17,20,24,30};
int n= SZA(a);
int cache[100];
int road(int len)
{
anish++;
if(cache[len]!=-1)
return cache[len];
if(len<=0)
return 0;
int max=0;
int i;
for(i=1;(i<n && len>=i);i++)
{
max=MAX(max,a[i]+road(len-i));
}
return cache[len]=max;
}
void f()
{
anish=13;
}
int main()
{
int i;
for(i=0;i<=13;i++)
cache[i]=-1;
int len=10;
// f();
printf("%d %d\n",road(len),anish);
return 0;
}
In this, road() is a recursive function and I want to calculate the number of times this function is being executed. So, I am doing this via a global variable anish.
But the value of anish is not changing in this road() function, while in function f() value of anish is being modified.
Any reason for this absurd behavior?
your c code shows an outdated anish variable
succesive printf's shows different value
this has something to do with c's internals
it has something to do with this : Parameter evaluation order before a function calling in C
loki astari said:
The order that function parameters are evaluated is unspecified
behavior. (This won't make your program crash, explode, or order
pizza... unlike undefined behavior.)
The only requirement is that all parameters must be fully evaluated
before the function is called.
In
printf("%d %d\n",road(len),anish);
the order in which the arguments are evaluated is unspecified. In this case, it seems anish is evaluated before road(len), so the value passed to printf is the unmodified value.
Evaluate road(len) before calling printf and store the result in a temporary variable.
Try this instead:
int main()
{ int i;
for(i=0;i<=13;i++)
cache[i]=-1;
int len=10;
// f();
printf("%d\n",road(len));
printf("%d\n", anish);
return 0;
}
Most likely what is happening is printf() is using the value of anish before road(len) returns.
See this for the details.
If you do it like this, it'll work:
printf("%d ",road(len));
printf("%d\n",anish);
may be its because of something inside the printf definition,

How can I cast a void function pointer in C?

Consider:
#include <stdio.h>
int f() {
return 20;
}
int main() {
void (*blah)() = f;
printf("%d\n",*((int *)blah())()); // Error is here! I need help!
return 0;
}
I want to cast 'blah' back to (int *) so that I can use it as a function to return 20 in the printf statement, but it doesn't seem to work. How can I fix it?
This might fix it:
printf("%d\n", ((int (*)())blah)() );
Your code appears to be invoking the function pointed to by blah, and then attempting to cast its void return value to int *, which of course can't be done.
You need to cast the function pointer before invoking the function. It is probably clearer to do this in a separate statement, but you can do it within the printf call as you've requested:
printf("%d\n", ((int (*)())blah)() );
Instead of initializing a void pointer and recasting later on, initialize it as an int pointer right away (since you already know it's an int function):
int (*blah)() = &f; // I believe the ampersand is optional here
To use it in your code, you simply call it like so:
printf("%d\n", (*blah)());
typedef the int version:
typedef int (*foo)();
void (*blah)() = f;
foo qqq = (foo)(f);
printf("%d\n", qqq());

Resources