Arithmetic on function address

Discussion in 'C Programming' started by pete b, May 28, 2010.

  1. pete b

    pete b Guest

    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?
     
    pete b, May 28, 2010
    #1
    1. Advertising

  2. pete b

    Dann Corbit Guest

    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.
     
    Dann Corbit, May 28, 2010
    #2
    1. Advertising

  3. 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) <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"
     
    Keith Thompson, May 28, 2010
    #3
  4. pete b

    Fred Guest

    On May 28, 2:19 pm, Dann Corbit <> wrote:
    > In article <htpano$>,
    > 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
     
    Fred, May 28, 2010
    #4
  5. 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) <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"
     
    Keith Thompson, May 28, 2010
    #5
  6. Keith Thompson <> 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.
     
    Ben Bacarisse, May 29, 2010
    #6
  7. Ben Bacarisse <> writes:
    > Keith Thompson <> 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) <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"
     
    Keith Thompson, May 29, 2010
    #7
  8. pete b

    pete b Guest

    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.
     
    pete b, May 29, 2010
    #8
  9. Keith Thompson <> 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.
     
    Ben Bacarisse, May 29, 2010
    #9
  10. 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.
     
    Ben Bacarisse, May 29, 2010
    #10
  11. Ben Bacarisse <> writes:
    > Keith Thompson <> 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.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 29, 2010
    #11
  12. pete b

    pete b Guest

    Ben Bacarisse writes:
    > 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.


    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.
     
    pete b, May 29, 2010
    #12
  13. pete b

    Eric Sosman Guest

    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
    lid
     
    Eric Sosman, May 29, 2010
    #13
  14. pete b <> writes:

    > Ben Bacarisse writes:
    >> pete b <> 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.
     
    Ben Bacarisse, May 29, 2010
    #14
  15. pete b

    Stargazer Guest

    On May 30, 12:37 am, pete b <> wrote:
    > Ben Bacarisse writes:
    > > 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.

    >
    > 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
     
    Stargazer, May 30, 2010
    #15
  16. On Sun, 30 May 2010 01:27:28 -0700 (PDT), Stargazer
    <> wrote:

    >On May 30, 12:37 am, pete b <> wrote:
    >> Ben Bacarisse writes:
    >> > 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.

    >>
    >> 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
     
    Barry Schwarz, May 31, 2010
    #16
  17. pete b

    Stargazer Guest

    On May 31, 3:13 am, Barry Schwarz <> 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
     
    Stargazer, May 31, 2010
    #17
  18. On Mon, 31 May 2010 02:07:37 -0700 (PDT), Stargazer
    <> wrote:

    >On May 31, 3:13 am, Barry Schwarz <> 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
     
    Barry Schwarz, May 31, 2010
    #18
  19. Barry Schwarz <> writes:
    > On Mon, 31 May 2010 02:07:37 -0700 (PDT), Stargazer
    > <> 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) <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"
     
    Keith Thompson, May 31, 2010
    #19
  20. pete b

    Stargazer Guest

    On May 31, 9:58 pm, Barry Schwarz <> wrote:

    > <> wrote:
    > >On May 31, 3:13 am, Barry Schwarz <> 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
     
    Stargazer, Jun 1, 2010
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stephen Biggs

    Arithmetic on function address

    Stephen Biggs, Apr 23, 2004, in forum: C Programming
    Replies:
    21
    Views:
    726
    Dan Pop
    Apr 28, 2004
  2. joshc
    Replies:
    5
    Views:
    564
    Keith Thompson
    Mar 31, 2005
  3. joshc
    Replies:
    16
    Views:
    485
    Joe Wright
    Jun 15, 2006
  4. Address Arithmetic

    , Jul 6, 2006, in forum: C++
    Replies:
    14
    Views:
    711
    Old Wolf
    Jul 10, 2006
  5. Frederick Gotham

    Byte Address Arithmetic Debate

    Frederick Gotham, Nov 19, 2006, in forum: C++
    Replies:
    24
    Views:
    751
    Frederick Gotham
    Nov 21, 2006
Loading...

Share This Page