Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Arithmetic on function address

Reply
Thread Tools

Arithmetic on function address

 
 
pete b
Guest
Posts: n/a
 
      05-28-2010
Given this code:
void f(void){}
int main(void){return (int)f+5;}

Is there anything wrong with this in terms of the standards? Is this
legal C code? One compiler I'm working with compiles this quietly, even
with the most stringent and pedantic ANSI and warning levels, but
generates code that only loads the address of "f" and fails to make the
addition before returning a value from "main".

GCC "does the right thing".

Is there something I'm missing?
 
Reply With Quote
 
 
 
 
Dann Corbit
Guest
Posts: n/a
 
      05-28-2010
In article <htpano$i3h$>,
says...
>
> Given this code:
> void f(void){}
> int main(void){return (int)f+5;}
>
> Is there anything wrong with this in terms of the standards? Is this
> legal C code? One compiler I'm working with compiles this quietly, even
> with the most stringent and pedantic ANSI and warning levels, but
> generates code that only loads the address of "f" and fails to make the
> addition before returning a value from "main".
>
> GCC "does the right thing".
>
> Is there something I'm missing?


Interesting question. I do get warnings:

dcorbit@DCORBIT2008 /c/tmp
$ gcc -W -Wall -ansi -pedantic bozuk.c
bozuk.c: In function 'main':
bozuk.c:3:12: warning: cast from pointer to integer of different size

dcorbit@DCORBIT2008 /c/tmp
$ cat bozuk.c
void f(void) {}
int main(void) {
return (int)f+5;
}

c:\tmp>cl /W4 /Ox bozuk.c
Microsoft (R) C/C++ Optimizing Compiler Version 15.00.30729.01 for x64
Copyright (C) Microsoft Corporation. All rights reserved.

bozuk.c
bozuk.c(3) : warning C4305: 'type cast' : truncation from 'void (__cdecl
*)(void)' to 'int'
Microsoft (R) Incremental Linker Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.

/out:bozuk.exe
bozuk.obj

Now, the type of f is a function pointer. Since f+5 is equivalent to f
[5] and since f is not an array of 6 or more function pointers (but
rather, a single pointer), I guess that the behavior is undefined.
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      05-28-2010
pete b <> writes:
> Given this code:
> void f(void){}
> int main(void){return (int)f+5;}
>
> Is there anything wrong with this in terms of the standards? Is this
> legal C code? One compiler I'm working with compiles this quietly, even
> with the most stringent and pedantic ANSI and warning levels, but
> generates code that only loads the address of "f" and fails to make the
> addition before returning a value from "main".
>
> GCC "does the right thing".
>
> Is there something I'm missing?


The code violates no constraints as far as I can tell, so the
implementation is not required to diagnose any problems.

Conversion from a pointer-to-function type to an integral type is
not forbidden, but nothing in the standard defines its behavior,
so the behavior is undefined by omission.

The only values the standard says you can return from main are 0,
EXIT_SUCCESS (likely to be 0), and EXIT_FAILURE. Other values are
permitted, but might communicate strange and/or meaningless things
to the environment.

This looks like a theoretical question (which is fine, of course),
but if it isn't, what are you trying to do?

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Fred
Guest
Posts: n/a
 
      05-28-2010
On May 28, 2:19*pm, Dann Corbit <dcor...@connx.com> wrote:
> In article <htpano$i3...@speranza.aioe.org>, pe...@tradermail.info
> says...
>
>
>
> > Given this code:
> > void f(void){}
> > int main(void){return (int)f+5;}

>
> > Is there anything wrong with this in terms of the standards? *Is this
> > legal C code? *One compiler I'm working with compiles this quietly, even
> > with the most stringent and pedantic ANSI and warning levels, but
> > generates code that only loads the address of "f" and fails to make the
> > addition before returning a value from "main".

>
> > GCC "does the right thing".

>
> > Is there something I'm missing?

>
> Interesting question. *I do get warnings:
>
> dcorbit@DCORBIT2008 /c/tmp
> $ gcc -W -Wall -ansi -pedantic bozuk.c
> bozuk.c: In function 'main':
> bozuk.c:3:12: warning: cast from pointer to integer of different size
>
> dcorbit@DCORBIT2008 /c/tmp
> $ cat bozuk.c
> void f(void) {}
> int main(void) {
> * * return (int)f+5;
>
> }
>
> c:\tmp>cl /W4 /Ox bozuk.c
> Microsoft (R) C/C++ Optimizing Compiler Version 15.00.30729.01 for x64
> Copyright (C) Microsoft Corporation. *All rights reserved.
>
> bozuk.c
> bozuk.c(3) : warning C4305: 'type cast' : truncation from 'void (__cdecl
> *)(void)' to 'int'
> Microsoft (R) Incremental Linker Version 9.00.30729.01
> Copyright (C) Microsoft Corporation. *All rights reserved.
>
> /out:bozuk.exe
> bozuk.obj
>
> Now, the type of f is a function pointer. *Since f+5 is equivalent to f
> [5] and since f is not an array of 6 or more function pointers (but
> rather, a single pointer), I guess that the behavior is undefined.


The warnings are due to casting f to an int. It is likely that on your
system a function pointer is 64 bits, and an int is 32 bits.

--
Fred K
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-28-2010
Dann Corbit <> writes:
> In article <htpano$i3h$>,
> says...
>>
>> Given this code:
>> void f(void){}
>> int main(void){return (int)f+5;}

[snip]
> Interesting question. I do get warnings:

[...]
> Now, the type of f is a function pointer. Since f+5 is equivalent to f
> [5] and since f is not an array of 6 or more function pointers (but
> rather, a single pointer), I guess that the behavior is undefined.


No, f+5 would be equivalent to &(f[5]) (but only if f were an object
pointer). But f is converted to int before 5 is added to the result;
there's no pointer arithmetic happening.

For f+5 to make sense, f would have to point to an element of an array
of functions. There's no such thing in C.

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      05-29-2010
Keith Thompson <kst-> writes:

> pete b <> writes:
>> Given this code:
>> void f(void){}
>> int main(void){return (int)f+5;}
>>
>> Is there anything wrong with this in terms of the standards? Is this
>> legal C code?

<snip>
> The code violates no constraints as far as I can tell, so the
> implementation is not required to diagnose any problems.
>
> Conversion from a pointer-to-function type to an integral type is
> not forbidden, but nothing in the standard defines its behavior,
> so the behavior is undefined by omission.


Surely it is implementation defined (6.3.2.3 p6)?

<snip>
--
Ben.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-29-2010
Ben Bacarisse <> writes:
> Keith Thompson <kst-> writes:
>> pete b <> writes:
>>> Given this code:
>>> void f(void){}
>>> int main(void){return (int)f+5;}
>>>
>>> Is there anything wrong with this in terms of the standards? Is this
>>> legal C code?

> <snip>
>> The code violates no constraints as far as I can tell, so the
>> implementation is not required to diagnose any problems.
>>
>> Conversion from a pointer-to-function type to an integral type is
>> not forbidden, but nothing in the standard defines its behavior,
>> so the behavior is undefined by omission.

>
> Surely it is implementation defined (6.3.2.3 p6)?
>
> <snip>


Whoops, you're right. Conversion of a pointer-to-function to a
pointer-to-object, or vice versa, is undefined (except for null
pointers); that's what I was thinking of. Sorry about the
misinformation.

I just noticed something odd. C99 6.4.2.3p6 says:

Any pointer type may be converted to an integer type. Except as
previously specified, the result is implementation-defined. If
the result cannot be represented in the integer type, the
behavior is undefined. The result need not be in the range of
values of any integer type.

I see no "previously specified" behavior for pointer-to-integer
conversions. (Conversion of a constant 0 to a pointer yields a null
pointer, but nothing is guaranteed for the reverse conversion;
(int)(void*)0) needn't yield 0.)

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
pete b
Guest
Posts: n/a
 
      05-29-2010
Keith Thompson writes:
> This looks like a theoretical question (which is fine, of course), but
> if it isn't, what are you trying to do?


I am not trying to accomplish anything besides running the GCC testsuite
on some other compiler that I am trying to analyze. This is part of the
testsuite and passes with GCC, no problem... I was just wondering if this
is a bug in the compiler that I am trying to run on this code? I want to
be sure that this should generate code correctly before I cry "bug".
That is, that it should generate code to add the constant after the
pointer is converted to an integer.

Thanks for any help.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      05-29-2010
Keith Thompson <kst-> writes:
<snip>
> I just noticed something odd. C99 6.4.2.3p6 says:


Does C99 have different numbering from n1256.pdf or is that a typo?

> Any pointer type may be converted to an integer type. Except as
> previously specified, the result is implementation-defined. If
> the result cannot be represented in the integer type, the
> behavior is undefined. The result need not be in the range of
> values of any integer type.
>
> I see no "previously specified" behavior for pointer-to-integer
> conversions. (Conversion of a constant 0 to a pointer yields a null
> pointer, but nothing is guaranteed for the reverse conversion;
> (int)(void*)0) needn't yield 0.)


I was puzzled by that, too. My guess was that maybe there had been,
once, a requirement that a null pointer would convert back to (int)
zero.

--
Ben.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      05-29-2010
pete b <> writes:

> Keith Thompson writes:
>> This looks like a theoretical question (which is fine, of course), but
>> if it isn't, what are you trying to do?

>
> I am not trying to accomplish anything besides running the GCC testsuite
> on some other compiler that I am trying to analyze. This is part of the
> testsuite and passes with GCC, no problem... I was just wondering if this
> is a bug in the compiler that I am trying to run on this code? I want to
> be sure that this should generate code correctly before I cry "bug".
> That is, that it should generate code to add the constant after the
> pointer is converted to an integer.


You can't tell from the code if there is a bug! The fact that (int)f
(when f is the name of a function) is implementation defined means that
a conforming C implementation must document what happens. You have a
bug in the implementation if either (a) the documents don't say what
will happen or (b) the compiler does not do what the documents say.

--
Ben.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Address Arithmetic aistone@gmail.com C++ 14 07-10-2006 12:03 AM
Address of array behavior in pointer arithmetic joshc C Programming 16 06-15-2006 10:14 PM
A kind of arithmetic for subnetting and ip address management lily Cisco 0 05-08-2006 09:32 AM
Usual Arithmetic Conversions-arithmetic expressions joshc C Programming 5 03-31-2005 02:23 AM
Arithmetic on function address Stephen Biggs C Programming 21 04-28-2004 11:17 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57