Address of a constant

K

K. Jennings

I have a function f with the following prototype: int f(void *).
From my main() (or whatever) I can do things like

int x = 123456 ;
int y ;

y = f(&x) ;

which is fine. My question is, how can I pass the 123456 integer to f
without using the intermediate x variable? Naively, what I would like to
do is something like

y = f(&123456) ;

which of course results in a syntax errors.
 
B

Ben Pfaff

K. Jennings said:
I have a function f with the following prototype: int f(void *).
From my main() (or whatever) I can do things like

int x = 123456 ;

Note that 123456 is outside the portable range of int.
int y ;

y = f(&x) ;

which is fine. My question is, how can I pass the 123456 integer to f
without using the intermediate x variable? Naively, what I would like to
do is something like

y = f(&123456) ;

which of course results in a syntax errors.

In C99, you can use a compound literal, e.g.
y = f(&(int) {123456});
or
y = f((int[]) {123456});
(I'm no C99 expert so it's possible that one or both of these is
wrong for some reason.)

I don't think there's a way to do this in C89.
 
K

K. Jennings

Why not "int f(int);", which is more direct and safer.

Because in the case that I am interested in the data buffer fed
to f can contain lots of different data types, that will be dealt with
appropriately in the right contexts.
 
C

Chris Dollin

K. Jennings said:
I have a function f with the following prototype: int f(void *).
From my main() (or whatever) I can do things like

int x = 123456 ;
int y ;

y = f(&x) ;

which is fine. My question is, how can I pass the 123456 integer to f
without using the intermediate x variable?

You can't.
Naively, what I would like to
do is something like

y = f(&123456) ;

which of course results in a syntax errors.

Even if it worked, what's `f` going to do with it? It's
handed a pointer-to-object, but it doesn't know what
kind of object. It can pass it along to another
function that wants a `void*`, but the same applies
to /that/. It can store it in a `void*` variable,
but if that's to be pointful, someone somewhere has
to know what to do with it. It could `free` or `realloc`
it, but since your examples don't pass mallocated
store, that would be ... unwise.

Are you /sure/ that prototype is the one you want?
 
C

Christopher Benson-Manica

Chris Dollin said:
K. Jennings wrote:
Even if it worked, what's `f` going to do with it?

The same thing f would do with a pointer to an automatic int,
presumably. Obviously f() is intended to have some way of knowing
what the type of its argument is (as OP explicitly stated elsethread).
 
R

Richard Heathfield

Chris Dollin said:
You can't.

Yes, he can, by changing the prototype of f so that it expects int
rather than int *. Then he can pass the integer value like this:

y = f(123456);

provided, of course, that INT_MAX >= 123456 on his system.
 
C

Christopher Benson-Manica

K. Jennings said:
int x = 123456 ;
int y ;
y = f(&x) ;
My question is, how can I pass the 123456 integer to f
without using the intermediate x variable? Naively, what I would like to
do is something like
y = f(&123456) ;
which of course results in a syntax errors.

As has been stated, you can't do this. It's worth thinking about the
question of "Why not?", which is (*) that it would require such
integer constants to have storage associated with them, much like
string literals have associated storage. (Note that you can (**)
compute the address of a string literal; the resulting pointer has
type "pointer to array of char".)

(*) - Add grain of salt here; I am not a guru.

(**) - Assuming my informal test with gcc and my reading of the
standard are correct.
 
A

Army1987

K. Jennings said:
I have a function f with the following prototype: int f(void *).
From my main() (or whatever) I can do things like

int x = 123456 ;
int y ;

y = f(&x) ;

which is fine. My question is, how can I pass the 123456 integer to f
without using the intermediate x variable? Naively, what I would like to
do is something like

y = f(&123456) ;

which of course results in a syntax errors.

What are you trying to do, considering that the argument of f isn't even
const?
Supposing f is
int f(void *v)
{
return ++*(int *)v;
}
What do you expect to happen? All next occurrences of 123456 to behave as
if they were 123457?
More seriously, if f is actually a int f(const void*, const void*) you
use for qsort, and you want to use it to compare two int constants
without rewriting it, you may use temporary variables:

int flag;
{
tmp1 = 123456;
tmp2 = 42;
flag = f(&tmp1, &tmp2);
}

But you'd better tell *what* you are trying to do, than telling *how* you
want to do that, which could be the wrong way.
 
B

Ben Bacarisse

Chris Dollin said:
You can't.

I think (modulo arguments about the OP's real intent) you can.

It is unclear exactly what would constitute solution (e.g. no
compiler/platform constraints were given and what does "not using an
intermediate variable" really mean, etc) but you *can* do what he/she
*seems* to want to do in standard C:

y = f((int []){123456});

Someone else already pointed this out, but it seems worth another go.
 
K

Kenneth Brody

K. Jennings said:
I have a function f with the following prototype: int f(void *).
From my main() (or whatever) I can do things like

int x = 123456 ;
int y ;

y = f(&x) ;

which is fine. My question is, how can I pass the 123456 integer to f
without using the intermediate x variable? Naively, what I would like to
do is something like

y = f(&123456) ;

which of course results in a syntax errors.

Imagine the consequence of the following:

int f(int *param)
{
return (*param)++ ;
}

Imagine, further, if the compiler combined all such references
to constants, as it can with string literals:

y = f(&123456);
z = f(&123456);

As I recall, FORTRAN passed parameters by reference, and it was
indeed possible to modify "constants" in such a manner.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
C

Chris Torek

Indeed. As others have noted, C does not have this, but C99 does
have something similar that will work. (Back before there was a
C Standard, VMS C allowed "&constant" in just this way.)

Imagine the consequence of the following:

int f(int *param)
{
return (*param)++ ;
}

Imagine, further, if the compiler combined all such references
to constants, as it can with string literals:

y = f(&123456);
z = f(&123456);

If the constants are placed in some kind of physically-read-only
memory (write-protected RAM, or ROM, for instance), the attempt
to modify the constant will be trapped or ignored. Otherwise,
"bad things happen". :)
As I recall, FORTRAN passed parameters by reference, and it was
indeed possible to modify "constants" in such a manner.

The mechanism in Fortran was not specified, and if a compiler used
value-result, it could ignore attempts to modify constants this way.
Most did tend to use by-value, though, and one could often achieve
"interesting" effects by changing constants.
 
D

David Thompson

The mechanism in Fortran was not specified, and if a compiler used
Right.

value-result, it could ignore attempts to modify constants this way.

Value-result, in the days before INTENT, _would_ modify the caller's
'constant' just like by-reference, from one call to another call or
use. It would be distinguishable from by-reference only by multiple
references (aliasing) within one call plus its subcalls. And such
problems during one call would at least be near(er) to the cause and
easier to debug; the real bastard is an unintended change caused in
one part of the program that screws up things much later and far away.

By-value (in only) wouldn't, but it wouldn't provide the FORTRAN (pre
INTENT) semantics of allowing changes to any argument.
Most did tend to use by-value, though, and one could often achieve
"interesting" effects by changing constants.

Just for the record, obviously you meant by-reference there.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top