Odd behavior with odd code

Discussion in 'C Programming' started by Michael Speer, Feb 16, 2007.

  1. #include <stdio.h>
    #include <stdlib.h>

    int main( int argc , char ** argv )
    {
    looper:
    printf( "%d\n" , argc ) ;
    printf( "%x\n" , &&looper ) ;
    if( argc > 0 )
    ((int(*)(int,char**))&&looper)( 0 , argv ) ;
    return 0 ;
    }

    Linux version 2.6.17-10-386 (root@vernadsky) (gcc version 4.1.2
    20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)) #2 Fri Oct 13 18:41:40
    UTC 2006 (Ubuntu 2.6.17-10.33-386)

    gcc version 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)

    On this box the code above compiles but runs in an infinite loop.
    Instead of pushing the stack pointer and calling the label location as
    a function with the arguments given as I expected, the compiler
    instead acts as though it was a simple goto and reuses the original
    arguments.

    gdb backtrace sees only a single frame.
    Michael Speer, Feb 16, 2007
    #1
    1. Advertising

  2. Michael Speer

    santosh Guest

    Michael Speer wrote:
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > int main( int argc , char ** argv )
    > {
    > looper:
    > printf( "%d\n" , argc ) ;
    > printf( "%x\n" , &&looper ) ;
    > if( argc > 0 )
    > ((int(*)(int,char**))&&looper)( 0 , argv ) ;
    > return 0 ;
    > }
    >
    > Linux version 2.6.17-10-386 (root@vernadsky) (gcc version 4.1.2
    > 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)) #2 Fri Oct 13 18:41:40
    > UTC 2006 (Ubuntu 2.6.17-10.33-386)
    >
    > gcc version 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)
    >
    > On this box the code above compiles but runs in an infinite loop.
    > Instead of pushing the stack pointer and calling the label location as
    > a function with the arguments given as I expected, the compiler
    > instead acts as though it was a simple goto and reuses the original
    > arguments.
    >
    > gdb backtrace sees only a single frame.


    This group discusses ISO C. Your code uses gcc specific extensions and
    thus it's behaviour is outside the scope of this group. Maybe a gcc
    mailing list or group would be more appropriate.
    santosh, Feb 16, 2007
    #2
    1. Advertising

  3. In article <>,
    Michael Speer <> wrote:

    >#include <stdio.h>
    >#include <stdlib.h>


    You do not appear to be using anything from stdlib.h

    >int main( int argc , char ** argv )
    >{
    > looper:
    > printf( "%d\n" , argc ) ;
    > printf( "%x\n" , &&looper ) ;


    A label is not an object, and cannot have its address taken.
    A label is not even in the same namespace as objects.

    If you did manage to take the address of a label, then
    a %x format would not be the correct format with which to print
    out the address. You need %p to print out pointers.

    > if( argc > 0 )
    > ((int(*)(int,char**))&&looper)( 0 , argv ) ;
    > return 0 ;
    >}


    >Linux version 2.6.17-10-386 (root@vernadsky) (gcc version 4.1.2
    >20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)) #2 Fri Oct 13 18:41:40
    >UTC 2006 (Ubuntu 2.6.17-10.33-386)
    >
    >gcc version 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)
    >
    >On this box the code above compiles but runs in an infinite loop.


    You didn't compile with C, you compiled with gcc. gcc implements
    a C-like language, but does not implement C unless you use a
    number of compile options to force it to compile the way a C compiler
    should. For assistance with the C-like language implemented
    by gcc, you would need to ask in a gcc newsgroup. (You won't be
    able to compile your program as real C.)

    >Instead of pushing the stack pointer and calling the label location as
    >a function with the arguments given as I expected, the compiler
    >instead acts as though it was a simple goto and reuses the original
    >arguments.


    Anything can happen when you violate C semantics.

    --
    Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
    Walter Roberson, Feb 16, 2007
    #3
  4. "Michael Speer" <> wrote:

    >#include <stdio.h>
    >#include <stdlib.h>
    >
    >int main( int argc , char ** argv )
    >{
    > looper:
    > printf( "%d\n" , argc ) ;
    > printf( "%x\n" , &&looper ) ;
    > if( argc > 0 )
    > ((int(*)(int,char**))&&looper)( 0 , argv ) ;
    > return 0 ;
    >}
    >...
    >
    >On this box the code above compiles but runs in an infinite loop.
    >Instead of pushing the stack pointer and calling the label location as
    >a function with the arguments given as I expected, the compiler
    >instead acts as though it was a simple goto and reuses the original
    >arguments.


    I don't understand what is the meaning of &&looper, "the address of
    the address of a label?". A label is neither a function nor an object,
    so the unary & can not be applied to it. It this program produced
    "expected results" in some other system that is sheer luck. (Or lack
    thereof)


    From WG14/N1124 Committee Draft — May 6, 2005 ISO/IEC 9899:TC2

    6.5.3.2 Address and indirection operators

    Constraints

    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.

    2 The operand of the unary * operator shall have pointer type.

    Semantics

    3 The unary & operator yields the address of its operand. If the
    operand has type ‘‘type’’, the result has type ‘‘pointer to type’’. If
    the operand is the result of a unary * operator, neither that operator
    nor the & operator is evaluated and the result is as if both were
    omitted, except that the constraints on the operators still apply and
    the result is not an lvalue. Similarly, if the operand is the result
    of a [] operator, neither the & operator nor the unary * that is
    implied by the [] is evaluated and the result is as if the & operator
    were removed and the [] operator were changed to a + operator.
    Otherwise, the result is a pointer to the object or function
    designated by its operand.

    Roberto Waltman

    [ Please reply to the group,
    return address is invalid ]
    Roberto Waltman, Feb 16, 2007
    #4
  5. Roberto Waltman wrote:
    > "Michael Speer" <> wrote:
    >
    > >#include <stdio.h>
    > >#include <stdlib.h>
    > >
    > >int main( int argc , char ** argv )
    > >{
    > > looper:
    > > printf( "%d\n" , argc ) ;
    > > printf( "%x\n" , &&looper ) ;
    > > if( argc > 0 )
    > > ((int(*)(int,char**))&&looper)( 0 , argv ) ;
    > > return 0 ;
    > >}
    > >...
    > >
    > >On this box the code above compiles but runs in an infinite loop.
    > >Instead of pushing the stack pointer and calling the label location as
    > >a function with the arguments given as I expected, the compiler
    > >instead acts as though it was a simple goto and reuses the original
    > >arguments.

    >
    > I don't understand what is the meaning of &&looper, "the address of
    > the address of a label?". A label is neither a function nor an object,
    > so the unary & can not be applied to it. It this program produced
    > "expected results" in some other system that is sheer luck. (Or lack
    > thereof)


    It's not two instances of &, but it's one instance of &&, just like
    how ++1 is invalid even though it would make sense if read as + + 1.
    And the use of && as a unary operator applied to a label is a compiler
    extension for which a diagnostic is correctly issued in conforming
    mode.
    =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Feb 16, 2007
    #5
  6. Santosh : I will not bother this group again with problems that
    apparently do not extend to C but in.

    Walter : on my system the sizeof( int ) == sizeof( pointer ) and
    pointers are printed in hex so it printed the same, though I know it
    is not guaranteed. Thank you for pointing out the appropriate %p
    format symbol. Your insight of gcc implementing a C-like language
    that deviates from the standard is also welcomed.

    Roberto : I do not know why &&label takes the address of the label,
    but it seems to do so readily. It is likely, judging from Santosh, a
    gcc extension or a fluke. I got this informations from another thread
    from which the explanation was absent.

    Thank you for your comments.
    Michael Speer, Feb 16, 2007
    #6
  7. Michael Speer

    CBFalconer Guest

    Michael Speer wrote:
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > int main( int argc , char ** argv )
    > {
    > looper:
    > printf( "%d\n" , argc ) ;
    > printf( "%x\n" , &&looper ) ;
    > if( argc > 0 )
    > ((int(*)(int,char**))&&looper)( 0 , argv ) ;
    > return 0 ;
    > }


    Why this contortion? Why not simply:

    #include <stdio.h>
    #include <stdlib.h>

    int main(int argc, char ** argv) {
    printf( "%d\n" , argc ) ;
    if(argc > 0) return main(0, argv)
    return 0 ;
    }

    --
    <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
    <http://www.securityfocus.com/columnists/423>

    "A man who is right every time is not likely to do very much."
    -- Francis Crick, co-discover of DNA
    "There is nothing more amazing than stupidity in action."
    -- Thomas Matthews
    CBFalconer, Feb 16, 2007
    #7
  8. "Michael Speer" wrote:
    >...
    >Roberto : I do not know why &&label takes the address of the label,
    >but it seems to do so readily. It is likely, judging from Santosh, a
    >gcc extension or a fluke...


    I learned something new: This is GCC extension.

    From

    http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Labels-as-Values.html#Labels-as-Values

    5.3 Labels as Values

    You can get the address of a label defined in the
    current function (or a containing function) with
    the unary operator `&&' ...

    Sorry, can not help with your original question...


    Roberto Waltman

    [ Please reply to the group,
    return address is invalid ]
    Roberto Waltman, Feb 16, 2007
    #8
  9. Roberto Waltman <> writes:
    > "Michael Speer" <> wrote:
    >>#include <stdio.h>
    >>#include <stdlib.h>
    >>
    >>int main( int argc , char ** argv )
    >>{
    >> looper:
    >> printf( "%d\n" , argc ) ;
    >> printf( "%x\n" , &&looper ) ;
    >> if( argc > 0 )
    >> ((int(*)(int,char**))&&looper)( 0 , argv ) ;
    >> return 0 ;
    >>}
    >>...
    >>
    >>On this box the code above compiles but runs in an infinite loop.
    >>Instead of pushing the stack pointer and calling the label location as
    >>a function with the arguments given as I expected, the compiler
    >>instead acts as though it was a simple goto and reuses the original
    >>arguments.

    >
    > I don't understand what is the meaning of &&looper, "the address of
    > the address of a label?". A label is neither a function nor an object,
    > so the unary & can not be applied to it. It this program produced
    > "expected results" in some other system that is sheer luck. (Or lack
    > thereof)

    [...]

    That's actually the "&&" operator, a gcc extension that takes the
    address of a label and yields a result of type void*.

    Allowing conversion of a value of type void* to a pointer-to-function
    type is also a gcc extension.

    See the gcc documentation or gnu.gcc.help for more information.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Feb 16, 2007
    #9
  10. Keith Thompson <> wrote:
    >Roberto Waltman <> writes:
    >>
    >> I don't understand what is the meaning of &&looper, "the address of
    >> the address of a label?"...

    >
    >That's actually the "&&" operator, a gcc extension that takes the
    >address of a label and yields a result of type void*.
    >...
    >See the gcc documentation or gnu.gcc.help for more information.


    Thanks, I already did. Harald van D?k and Michael Speer pointed in
    that direction.
    I have used gcc in several projects, but always as gcc -ansi -Wall
    -pedantic -std= ...


    Roberto Waltman

    [ Please reply to the group,
    return address is invalid ]
    Roberto Waltman, Feb 16, 2007
    #10
  11. In article <>,
    CBFalconer <> wrote:

    >> int main( int argc , char ** argv )
    >> {
    >> looper:
    >> printf( "%d\n" , argc ) ;
    >> printf( "%x\n" , &&looper ) ;
    >> if( argc > 0 )
    >> ((int(*)(int,char**))&&looper)( 0 , argv ) ;
    >> return 0 ;
    >> }


    >Why this contortion? Why not simply:
    >
    >#include <stdio.h>
    >#include <stdlib.h>
    >
    >int main(int argc, char ** argv) {
    > printf( "%d\n" , argc ) ;
    > if(argc > 0) return main(0, argv)
    > return 0 ;
    >}


    Presumably that doesn't exhibit the "bug" of looping indefinitely.

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
    Richard Tobin, Feb 16, 2007
    #11
  12. CBFalconer : I was thinking of writing a hack that would allow me to
    store the label addresses in order to call a function starting at a
    midway point. If I then stored static variables in a structure
    outside of the list than I could create a very simple generator-like
    function that starts in a different spot each time it is called
    without using a switch or even recurses back to different points
    within itself. Basically I was playing at what I could make the code
    do. Not production.

    Keith Thompson : Thank you for the information. I did not come across
    it until after posting.

    Just for the information of anyone here that wants it :

    While compiling this code with no options or -O0 ( gcc optimization
    zero ) caused it to fall into a recursive loop ( seemingly from
    treating the function call as a goto ) , compiling it as -O6 ( gcc
    maximum optimization ) caused it to work, redoing the stack to hold
    the parameters properly.

    Thank you for your comments.
    Michael Speer, Feb 16, 2007
    #12
  13. Michael Speer

    Ian Collins Guest

    Michael Speer wrote:
    > CBFalconer : I was thinking of writing a hack that would allow me to
    > store the label addresses in order to call a function starting at a
    > midway point. If I then stored static variables in a structure
    > outside of the list than I could create a very simple generator-like
    > function that starts in a different spot each time it is called
    > without using a switch or even recurses back to different points
    > within itself. Basically I was playing at what I could make the code
    > do. Not production.
    >

    Are you trying to implement coroutines?

    --
    Ian Collins.
    Ian Collins, Feb 16, 2007
    #13
  14. On Feb 16, 5:55 pm, Ian Collins <> wrote:
    >
    > Are you trying to implement coroutines?
    >
    > --
    > Ian Collins.


    The whole of my immediate intent was to discern if it was even
    possible to take the address of a label and use casting to access the
    code in a function at an intermediate point. I had ideas ( the
    generator or partial recursion ) of things it might be used for. From
    what I know of them coroutines would be something that could be
    implemented using this type of behavior. That is, if one wished to
    implement them by way of the misuse of a gcc extension that when
    misused thusly only compiles with the `-O6' switch being passed to the
    compiler. :)
    Michael Speer, Feb 17, 2007
    #14
  15. Michael Speer

    CBFalconer Guest

    Michael Speer wrote:
    >
    > CBFalconer : I was thinking of writing a hack that would allow me to
    > store the label addresses in order to call a function starting at a
    > midway point. If I then stored static variables in a structure
    > outside of the list than I could create a very simple generator-like
    > function that starts in a different spot each time it is called
    > without using a switch or even recurses back to different points
    > within itself. Basically I was playing at what I could make the code
    > do. Not production.
    >
    > Keith Thompson : Thank you for the information. I did not come across
    > it until after posting.


    I never wrote anything as foolish as that. I have similar doubts
    about Keiths authorship, but we'll let him speak for himself. If
    you just use proper Usenet quoting this sort of foul-up will have a
    hard time occurring.

    --
    <http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
    <http://www.securityfocus.com/columnists/423>

    "A man who is right every time is not likely to do very much."
    -- Francis Crick, co-discover of DNA
    "There is nothing more amazing than stupidity in action."
    -- Thomas Matthews
    CBFalconer, Feb 17, 2007
    #15
  16. CBFalconer <> writes:
    > Michael Speer wrote:
    >>
    >> CBFalconer : I was thinking of writing a hack that would allow me to
    >> store the label addresses in order to call a function starting at a
    >> midway point. If I then stored static variables in a structure
    >> outside of the list than I could create a very simple generator-like
    >> function that starts in a different spot each time it is called
    >> without using a switch or even recurses back to different points
    >> within itself. Basically I was playing at what I could make the code
    >> do. Not production.
    >>
    >> Keith Thompson : Thank you for the information. I did not come across
    >> it until after posting.

    >
    > I never wrote anything as foolish as that. I have similar doubts
    > about Keiths authorship, but we'll let him speak for himself. If
    > you just use proper Usenet quoting this sort of foul-up will have a
    > hard time occurring.


    The strings "CBFalconer :" and "Keith Thompson :" were, I'm sure,
    intended to address the following comments to us, not to imply that we
    had written them. (Note the lack of the word "wrote", or "writes", or
    anything similar).

    Posting separate followups quoting (some of) what each of us had
    written would have been more in keeping with usual Usenet practice,
    but combining both in a single followup is not horrid IMHO. The
    prefixes don't particularly look (to me) like attribution lines.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Feb 17, 2007
    #16
  17. Michael Speer

    Chris Torek Guest

    In article <>
    Michael Speer <> wrote:
    >While compiling this code


    [which, as a reminder that should also make this article stand-alone,
    was some code using gcc-specific extensions in ways other than those
    intended by the gcc-extension authors, in my opinion anyway]

    >with no options or -O0 ( gcc optimization zero ) caused it to fall
    >into a recursive loop ( seemingly from treating the function call
    >as a goto ) , compiling it as -O6 ( gcc maximum optimization )
    >caused it to work, redoing the stack to hold the parameters properly.


    That implies that either or both of the following are true:

    - gcc has a bug in dealing with this extension, or
    - you are not using the extension in a way that even gcc defines
    (i.e., you are invoking not only undefined-by-the-C-standard
    behavior, but even undefined-by-gcc-extension behavior).

    I believe the latter is true. The former may or may not also be
    true.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Feb 17, 2007
    #17
  18. "Roberto Waltman" <> wrote in message
    news:eek:...
    > http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Labels-as-Values.html#Labels-as-Values
    >
    > 5.3 Labels as Values
    >
    > You can get the address of a label defined in the
    > current function (or a containing function) with
    > the unary operator `&&' ...
    >
    > Sorry, can not help with your original question...


    seems like a useless feature to me. even in that article they recommend
    "just use switch"
    Serve Laurijssen, Feb 17, 2007
    #18
  19. "Michael Speer" <> wrote in message
    news:...
    > On Feb 16, 5:55 pm, Ian Collins <> wrote:
    >> Are you trying to implement coroutines?

    >
    > The whole of my immediate intent was to discern if it was even
    > possible to take the address of a label and use casting to access the
    > code in a function at an intermediate point. I had ideas ( the
    > generator or partial recursion ) of things it might be used for. From
    > what I know of them coroutines would be something that could be
    > implemented using this type of behavior.


    The problem with casting a pointer-to-label to a pointer-to-function is that
    a label is not a function. The beginning of a function contains a prologue
    which builds the appropriate stack frame, retrieves arguments from wherever
    they are, etc. The compiler doesn't know it needs to do that at a label
    used as a function entry point -- in fact it probably can't do it even if it
    does know it needs to, since you can (usually) arrive at the label when it's
    _not_ being used as a function entry point.

    My guess is that this extension was created so that labels could be stored
    in variables and one could later do "goto variable;", Since there's no
    pointer-to-label type, void* is the logical choice for this abuse -- but you
    need some sort of construct to turn it back into a pointer-to-label (which
    I'm assuming goto can do) to actually make use of it. Instead, you're
    turning that pointer-to-object (which is really a pointer-to-label) into a
    pointer-to-function and trying to call it, which is so far out there it's
    not even just "wrong".

    There's probably a portable way to implement whatever you're trying to do;
    give us the problem first, not the solution, and we can try to help.

    S

    --
    Stephen Sprunk "Those people who think they know everything
    CCIE #3723 are a great annoyance to those of us who do."
    K5SSS --Isaac Asimov



    --
    Posted via a free Usenet account from http://www.teranews.com
    Stephen Sprunk, Feb 17, 2007
    #19
  20. Stephen Sprunk wrote:
    > "Michael Speer" <> wrote in message
    > news:...
    > > On Feb 16, 5:55 pm, Ian Collins <> wrote:
    > >> Are you trying to implement coroutines?

    > >
    > > The whole of my immediate intent was to discern if it was even
    > > possible to take the address of a label and use casting to access the
    > > code in a function at an intermediate point. I had ideas ( the
    > > generator or partial recursion ) of things it might be used for. From
    > > what I know of them coroutines would be something that could be
    > > implemented using this type of behavior.

    >
    > The problem with casting a pointer-to-label to a pointer-to-function is that
    > a label is not a function. The beginning of a function contains a prologue
    > which builds the appropriate stack frame, retrieves arguments from wherever
    > they are, etc. The compiler doesn't know it needs to do that at a label
    > used as a function entry point -- in fact it probably can't do it even if it
    > does know it needs to, since you can (usually) arrive at the label when it's
    > _not_ being used as a function entry point.
    >
    > My guess is that this extension was created so that labels could be stored
    > in variables and one could later do "goto variable;",


    A compiler must treat

    void f(void) {
    void *p;
    goto p;
    p:
    return;
    }

    as a jump to label p, not to the address referenced by variable p.

    [OT] In "GNU C", the syntax for a jump to a stored address is goto *p;
    [/OT]
    =?utf-8?B?SGFyYWxkIHZhbiBExLNr?=, Feb 17, 2007
    #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. Elliot M. Rodriguez

    PLEASE HELP = odd TextChanged behavior

    Elliot M. Rodriguez, Oct 21, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    314
    Elliot M. Rodriguez
    Oct 22, 2003
  2. Guest

    Step-thru code - odd behavior

    Guest, May 28, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    375
    Guest
    Jun 1, 2004
  3. =?Utf-8?B?Q2hyaXM=?=
    Replies:
    1
    Views:
    315
    Karl Seguin
    Jan 7, 2005
  4. news.microsoft.com

    EXTREMELY odd cookie behavior

    news.microsoft.com, Mar 15, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    303
    Joerg Jooss
    Mar 15, 2005
  5. Replies:
    3
    Views:
    493
    Bruce Barker
    Jun 21, 2005
Loading...

Share This Page