papaiatis
papaiatis

Reputation: 4291

C pass address of a function return value as function parameter

I have two functions:

void a(int * p);
int b();

Is it possible to pass the address of the return value of function b to function a something like this: a(&b()) ?

Upvotes: 5

Views: 2040

Answers (6)

James M
James M

Reputation: 16728

Only by using a temporary variable:

int result = b();
a(&result);

EDIT: Apparently there's also a way to do this using a compound literal, described in another answer here.

Upvotes: 3

VoidPointer
VoidPointer

Reputation: 3107

No you can't do that in C. Also note C doesn't have something called as reference as in C++.

For that C has pointers to achieve the same behaviour..

To achieve the same goal in C use temporary variable like,

int val;
val = b();
a( &val );    // & is called as "address of" operator in C

To answer why there is no reference in C, from my understanding pointer and reference are meant to achieve the same goal - minimizing or avoiding data copy. For this C's pointer is good enough, though technically both have some difference in C++ (taken for reference)

Upvotes: 1

dreamlax
dreamlax

Reputation: 95365

A compound literal seems to do the trick (requires a C99 compiler):

int a()
{
    return 5;
}

void b(int *a)
{
    // do something with a
    printf("%d\n", *a);
}

int main(void)
{
    b(&(int){ a() });
}

Output is 5.

Upvotes: 12

Shahbaz
Shahbaz

Reputation: 47583

No. C11 says that (emphasis mine):

6.5.3.2.1

The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

Now it clearly isn't a function, a [] or a unary *. Let's see what is an lvalue:

6.3.2.1

An lvalue is an expression (with an object type other than void) that potentially designates an object;64) if an lvalue does not designate an object when it is evaluated, the behavior is undefined. ...

64) The name ‘‘lvalue’’ comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object ‘‘locator value’’. What is sometimes called ‘‘rvalue’’ is in this International Standard described as the ‘‘value of an expression’’.

An obvious example of an lvalue is an identifier of an object. As a further example, if E is a unary expression that is a pointer to an object, *E is an lvalue that designates the object to which E points.

So in short, an lvalue designates an object. Since b() doesn't designate a specific object, it is not an lvalue. You can tell this by seeing also that b() = 2; is wrong.

Upvotes: 2

Hunter McMillen
Hunter McMillen

Reputation: 61540

You could pass a reference to b() as an argument to a then call b from a:

void a(void (*b)(int)) {
   // call b
   int local_var = b(<something>);
}

Upvotes: 0

Drew McGowen
Drew McGowen

Reputation: 11706

Nope - what would be the address of that return value? You need to store the return value in a variable, then pass the address of that variable in.

Upvotes: 2

Related Questions