Velocity Reviews - Computer Hardware Reviews

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

Reply
Thread Tools

Arithmetic on function address

 
 
Keith Thompson
Guest
Posts: n/a
 
      05-29-2010
Ben Bacarisse <(E-Mail Removed)> writes:
> Keith Thompson <(E-Mail Removed)> 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?


Typo; the numbering is the same (and I was using n1256 anyway).

>> 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.


Jun Woong posted the answer in comp.std.c:

6.3.1.2 Boolean type [which precedes 6.3.2.3]

When any scalar value is converted to _Bool, the result is 0 if
the value compares equal to 0; otherwise, the result is 1.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <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
Ben Bacarisse writes:
> pete b <(E-Mail Removed)> 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.


Ok... I understand this... that's just it... the code that this compiler
generates does the conversion and actually returns the address of the
function as an integer. It just silently discards the addition. If
this is implementation behavior, shouldn't it (as you say below about
compilers needing to give more than just what the standard says) either
complain about an invalid value or do the addition also, since it
accepts the conversion in the first place? The function address is
converted to an integer since this is what is returned, so the integer
value should be available for more computation if needed.

Any other behavior, such as what is happening here, is a bug in the
compiler IMHO.
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      05-29-2010
On 5/29/2010 5:37 PM, pete b wrote:
>
> Ok... I understand this... that's just it... the code that this compiler
> generates does the conversion and actually returns the address of the
> function as an integer. It just silently discards the addition. If
> this is implementation behavior, shouldn't it (as you say below about
> compilers needing to give more than just what the standard says) either
> complain about an invalid value or do the addition also, since it
> accepts the conversion in the first place? The function address is
> converted to an integer since this is what is returned, so the integer
> value should be available for more computation if needed.
>
> Any other behavior, such as what is happening here, is a bug in the
> compiler IMHO.


Looking up-thread, the code in question is:

void f(void){}
int main(void){return (int)f+5;}

What evidence do you have that the compiler "silently discards
the addition?" (Note that `return 42+5;' might not involve an
ADD instruction, either.)

--
Eric Sosman
(E-Mail Removed)lid
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      05-29-2010
pete b <(E-Mail Removed)> writes:

> Ben Bacarisse writes:
>> pete b <(E-Mail Removed)> writes:

<snip>
About (int)f+5; where f is a function.

>> 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.

>
> Ok... I understand this...


I think you missed the point. What does the documentation say?

> that's just it... the code that this compiler
> generates does the conversion and actually returns the address of the
> function as an integer. It just silently discards the addition. If
> this is implementation behavior, shouldn't it (as you say below about
> compilers needing to give more than just what the standard says) either
> complain about an invalid value or do the addition also, since it
> accepts the conversion in the first place?


Let me take a silly example: if the Bozo C compiler's document on
conformance states: "Converting a function pointer to an int gives a
numerical value 5 less than the bit pattern used to represent the
pointer would suggest" then it is permitted to optimise the +5 away.

All I was doing was saying that you can't look to the C standard for an
answer, you must look to the compiler's documentation.

> The function address is
> converted to an integer since this is what is returned, so the integer
> value should be available for more computation if needed.
>
> Any other behavior, such as what is happening here, is a bug in the
> compiler IMHO.


There may well be a bug, but you can't tell by logic alone. What does
the documentation say about this conversion? If it says the conversion
is well-defined (for example, the result is always in range) then you
can say that what you observe is a bug. Double check your facts and
report it. I say double check because it is surprisingly easy to get
odd results from code that is undefined for some other reason that you
have missed. Today's compilers are subtle beasts.

--
Ben.
 
Reply With Quote
 
Stargazer
Guest
Posts: n/a
 
      05-30-2010
On May 30, 12:37*am, pete b <(E-Mail Removed)> wrote:
> Ben Bacarisse writes:
> > pete b <(E-Mail Removed)> 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.

>
> Ok... I understand this... that's just it... the code that this compiler
> generates does the conversion and actually returns the address of the
> function as an integer. *It just silently discards the addition. *


Hardly. Address of "f" is constant, so when compiler converts that to
an integer, it becomes an integer constant. When you return sum of two
integers, the compiler is not required to generate extraneous code to
add them in run-time; it may just compute the result and return it
hardcoded. Consider as in (simplified) Eric's example if you had "int
main(void) {return 42+5;} the compiler may just generate appropriate
code to return 47, and you will see no traces of 42 or 5 in assembly
code.

This is usually done in optimizer stage; I believe if you turn on a
certain optimization level in GCC, it will also "discard" the
addition.

> If
> this *is implementation behavior, shouldn't it (as you say below about
> compilers needing to give more than just what the standard says) either
> complain about an invalid value or do the addition also, since it
> accepts the conversion in the first place? The function address is
> converted to an integer since this is what is returned, so the integer
> value should be available for more computation if needed.


Returned is that integer +5. If (int)f indeed was used in computation,
it would appear. The compiler happens to know all the "if needed" in
compile-time and may through everything that is not needed from
generated code.

Daniel
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      05-31-2010
On Sun, 30 May 2010 01:27:28 -0700 (PDT), Stargazer
<(E-Mail Removed)> wrote:

>On May 30, 12:37*am, pete b <(E-Mail Removed)> wrote:
>> Ben Bacarisse writes:
>> > pete b <(E-Mail Removed)> 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.

>>
>> Ok... I understand this... that's just it... the code that this compiler
>> generates does the conversion and actually returns the address of the
>> function as an integer. *It just silently discards the addition. *

>
>Hardly. Address of "f" is constant, so when compiler converts that to
>an integer, it becomes an integer constant. When you return sum of two


That may be true on your system, but on the two systems I commonly
use, it is fairly common for programs to execute at different
locations and the compiler will have no idea where any particular
instance of the program will reside. Neither will the compiler know
if a function that happens to reside between main and f has been
changed so that f is now at a different displacement from main. Trying
to compute (int)f+5 at compile time is not an option.

>integers, the compiler is not required to generate extraneous code to
>add them in run-time; it may just compute the result and return it
>hardcoded.


--
Remove del for email
 
Reply With Quote
 
Stargazer
Guest
Posts: n/a
 
      05-31-2010
On May 31, 3:13*am, Barry Schwarz <(E-Mail Removed)> wrote:
> >Hardly. Address of "f" is constant, so when compiler converts that to
> >an integer, it becomes an integer constant. When you return sum of two

>
> That may be true on your system, but on the two systems I commonly
> use, it is fairly common for programs to execute at different
> locations and the compiler will have no idea where any particular
> instance of the program will reside.


This is resolved during linking ("static" linking) or program loading
("dynamic" linking). Following your logic, we can never use addresses
of external functions or data as constants because they are not known
at compile time.

> Neither will the compiler know
> if a function that happens to reside between main and f has been
> changed so that f is now at a different displacement from main.


"f" is an address constant as defined in 6.6.9 of the C Standard. So,
as clause "6.6.2" defines:

"A constant expression can be evaluated during translation rather than
runtime, and
accordingly may be used in any place that a constant may be."

Daniel
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      05-31-2010
On Mon, 31 May 2010 02:07:37 -0700 (PDT), Stargazer
<(E-Mail Removed)> wrote:

>On May 31, 3:13*am, Barry Schwarz <(E-Mail Removed)> wrote:
>> >Hardly. Address of "f" is constant, so when compiler converts that to
>> >an integer, it becomes an integer constant. When you return sum of two

>>
>> That may be true on your system, but on the two systems I commonly
>> use, it is fairly common for programs to execute at different
>> locations and the compiler will have no idea where any particular
>> instance of the program will reside.

>
>This is resolved during linking ("static" linking) or program loading
>("dynamic" linking). Following your logic, we can never use addresses
>of external functions or data as constants because they are not known
>at compile time.
>
>> Neither will the compiler know
>> if a function that happens to reside between main and f has been
>> changed so that f is now at a different displacement from main.

>
>"f" is an address constant as defined in 6.6.9 of the C Standard. So,
>as clause "6.6.2" defines:
>
>"A constant expression can be evaluated during translation rather than
>runtime, and
>accordingly may be used in any place that a constant may be."


Except that 6.6-8 says

"Cast operators in an arithmetic constant expression shall only
convert arithmetic types to arithmetic types, except as part of an
operand to a sizeof operator whose result is an integer constant."

which seems to preclude treating (int)f+5 as a constant since the cast
converts a pointer type.

--
Remove del for email
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      05-31-2010
Barry Schwarz <(E-Mail Removed)> writes:
> On Mon, 31 May 2010 02:07:37 -0700 (PDT), Stargazer
> <(E-Mail Removed)> wrote:

[...]
>>"f" is an address constant as defined in 6.6.9 of the C Standard. So,
>>as clause "6.6.2" defines:
>>
>>"A constant expression can be evaluated during translation rather than
>>runtime, and
>>accordingly may be used in any place that a constant may be."

>
> Except that 6.6-8 says
>
> "Cast operators in an arithmetic constant expression shall only
> convert arithmetic types to arithmetic types, except as part of an
> operand to a sizeof operator whose result is an integer constant."
>
> which seems to preclude treating (int)f+5 as a constant since the cast
> converts a pointer type.


So ``(int)f+5'' isn't a constant expression, but since ``f'' is an
address constant it's likely that ``(int)f+5'' is still capable
of being evaluated at compile or link time.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <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
 
Stargazer
Guest
Posts: n/a
 
      06-01-2010
On May 31, 9:58*pm, Barry Schwarz <(E-Mail Removed)> wrote:

> <(E-Mail Removed)> wrote:
> >On May 31, 3:13*am, Barry Schwarz <(E-Mail Removed)> wrote:
> >> >Hardly. Address of "f" is constant, so when compiler converts that to
> >> >an integer, it becomes an integer constant. When you return sum of two

>
> >> That may be true on your system, but on the two systems I commonly
> >> use, it is fairly common for programs to execute at different
> >> locations and the compiler will have no idea where any particular
> >> instance of the program will reside.

>
> >This is resolved during linking ("static" linking) or program loading
> >("dynamic" linking). Following your logic, we can never use addresses
> >of external functions or data as constants because they are not known
> >at compile time.

>
> >> Neither will the compiler know
> >> if a function that happens to reside between main and f has been
> >> changed so that f is now at a different displacement from main.

>
> >"f" is an address constant as defined in 6.6.9 of the C Standard. So,
> >as clause "6.6.2" defines:

>
> >"A constant expression can be evaluated during translation rather than
> >runtime, and
> >accordingly may be used in any place that a constant may be."

>
> Except that 6.6-8 says
>
> "Cast operators in an arithmetic constant expression shall only
> convert arithmetic types to arithmetic types, except as part of an
> operand to a sizeof operator whose result is an integer constant."
>
> which seems to preclude treating (int)f+5 as a constant since the cast
> converts a pointer type.


The reason that pointer-to-integer conversions are not included in the
specification is, I think, that it may cause undefined behavior if
pointer value cannot be represented by the target integer type
(6.3.2.3.6). Not due to your reason - that "f" may change between
compile-time and run-time. It cannot since it's constant.

Note that conversion of integer constant to a pointer is explicitly
defined to result in an address constant - and according to 6.3.2.3.5
it may not cause undefined behavior.

Daniel
 
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