Returning and manipulating returned values in C - c

I'm having a hard time understanding the ways C handles returned values. Say for example we have:
int one = 0;
one = foo(); // Why isn't one being assigned 10?
// Clearly there is a difference between these two
printf("%d", one); // one is still 0
printf("%d", foo());
int foo()
{
return 10;
}
I can't seem to elucidate why there is a difference, and why one won't work over the other.
Thank you!

The following program's output is 1010. I compiled it with gcc -Wall -std=c99 main.c -o main.exe So, I think it's either your compiler problem, or you were wrong when claimed that printf("%d", one); prints zero.
#include <stdio.h>
int foo(void);
int main()
{
int one = 0;
one = foo();
printf("%d", one);
printf("%d", foo());
return 0;
}
int foo()
{
return 10;
}

The first argument of printf() is a const char *, (a pointer to an array of const char's), and with printf(foo()) you're trying to use a pointer to address 10, which obviously is out of the range of the program, causing it to not work. However, with printf("%d", one) you are telling printf to print out a number, which does work.

C function is not "function" as in math (or as in functional programming).
It just sequence of actions needed to obtain return value, and this mean that function may obtain side effects.
So think about your example - what if foo() will look like this:
int foo()
{
printf("some text");
return 10;
}
In other words, if you use variable with returned value - you just use value, but if you use function call, you do all computations needed for obtaining value.

Related

value changes after adding optimization flag in Clang

I have written a little program:
#include <stdio.h>
void tester() {
int x = 69;
}
void x() {
int x;
printf("%d\n", x);
}
int main() {
tester();
x();
}
which I expect to print out 69. It prints out 69 when I compile without optimization, but with O1-O3, it prints out large numbers. Why is this?
Attempting to read an uninitialized variable that never had its address taken triggers undefined behavior, which basically means that the program is not required to behave in any particular way.
It's clear that you were attempting to have the uninitialized variable x in the function x to get the "left over" value of x in tester. With optimization disabled this is how it happens to work. With optimization enabled, the compiler takes advantage of undefined behavior to assume it does not happen and make certain optimizations based on that fact.
So with optimization enabled, the compiler is basically assuming you won't read an uninialized variable which is why you see different output.
those 2 x variable are totally different things, they just happen to have the same name. If you want it to be the same x then you must create a global variable
int x;
void tester() {
x = 69;
}
void xx() {
printf("%d\n", x);
}
int main() {
tester();
xx();
}

Access function member using it address

Trying to access/print function member using following snippet
void func()
{
int i=4;
}
int *k = func + 4;
int main()
{
printf("%x\n", func);
printf("%x\n", k);
printf("%d\n", *(int *)k);
return 0;
}
and looking to get value of i through last printf statement but wondering if it is possible this way ?
output of program is:
400526
40052a
83641799
First of all, no, it's not possible at all to do in any reliable way.
And this idea does not make sense either. The variable i will typically not be exist nearby the function code. Also, it will typically be created at different places on different calls.
However, something that's possible is this:
int *func()
{
static int i=4;
return &i;
}
int *k;
int main()
{
k = func();
That's perfectly valid, even if the usefulness could be discussed.
But you will never be able to access it via an offset to the function pointer. At least not in a legal way.

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.

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,

c function chaining possible?

I was wondering if it is possible in C (89/90) to chain function calls, and where it is defined in the C spec. I assume this isn't possible since a google search reveals no mention of it.
I thought of this because of a related conversation with a friend of mine where he told me that given a function returning a struct, you cannot perform any operations on said struct within the same statement; instead, you have to assign the result of the function to a variable, and then manipulate the struct via the variable instead of directly from the function result itself. This leads me to believe that you can't chain functions either, but I can't seem to find these limitations discussed in the spec.
Edit : Sorry, I should have been specific on the return value. Assuming the function returns a function pointer, is it possible to dereference and call the result within the same statement, in fluent fashion?
For example, assuming getFunc returns a function pointer :
(*getFunc(getFuncParam))(otherFuncParam)
Or in the struct case, assuming a struct with an int member called count:
funcReturnsStruct(param).count++
Here's what function chaining looks like in C:
post_process(process(pre_process(data)));
Obviously, your friend is wrong. As long as the functions cooperate by accepting and returning the same type of value you can chain the calls all you like.
Contrast this with something like
data.pre_process().process().post_process();
The big difference is that in C (which has no encapsulation, hence no classes) functions have center stage while in more modern OO languages it's objects that get more attention.
Update: Sure it's possible to chain no matter what each function might return. For example:
int increase(int x) {
return x + 1;
}
typedef int (*increase_fp)(int);
increase_fp get_increase() {
return increase;
}
int main(void) {
printf("%d", get_increase()(1));
return 0;
}
See it in action.
a friend of mine where he told me that given a function returning a struct, you cannot perform any operations on said struct within the same statement
Your friend is correct in the sense that the return value of a function cannot be the target of an assignment (it's not an lvalue). IOW, you can't do something like
int foo(void) { int x = 5; return x; }
...
foo() = 6;
However, if the return type of a function is a struct or a union, you can apply the component selection operator to the return value, such as
int x = foo().memb;
Similarly, if the return type of the function is a pointer to a struct or a union, you can write
int x = foo()->memb;
And if the return value is a pointer to another function, you can call that other function like so:
int bar(int x) { ... }
int (*foo)(int x) { return bar; }
int x = foo(x)(y); // or (*foo(x))(y) -- the result of foo(x) is
// called with the argument y
although anyone who has to maintain or debug your code may beat you severely for it.
What you cannot do is something like
foo().memb= ...;
foo()->memb = ...;
which wouldn't make sense anyway, because the lifetime of the value returned by foo ends when the statement ends - you wouldn't be able to retrieve that modified value.
Your friend is wrong.
If we have:
struct Point3
{
float x, y, z;
};
const Point3 * point3_get_origin(void);
then you can certainly do:
printf("the origin's y coordinate is %f\n", point3_get_origin()->y);
The function returns a value of the given type, so the call of the function can be used wherever such a value is needed in an expression.
Do you mean something like this?
typedef void (*CALLBACK)(void);
CALLBACK getCallback();
void test()
{
getCallback()();
}
It compiles with no warning in GCC 4.6.1 (default std).
There's a much faster and easier way to answer this than posting here: try it.
#include <stdio.h>
struct s {
int a;
} s;
struct s * getS() {
s.a = 13;
return &s;
}
int main(int argc, char * const argv[]) {
printf("%d\n", getS()->a);
return 0;
}
% gcc test.c -o test -Wall -pedantic
% ./test
13
%
Not so much as a pedantic warning. Expected output. Looks like it's perfectly fine. However, as has been pointed out, it would be better to store the return value and check for errors.

Resources