How does the compiler do with this code? - Linux

This is a discussion on How does the compiler do with this code? - Linux ; Random832 wrote: >2006-12-19 , >Floyd L. Davidson wrote: >>>>>> Actually it would be assumed to be >>>>>> >>>>>> int printf( const char * restrict format, ... ); >>> >>>If, as I suspect, you don't actually believe that, it would be ...

+ Reply to Thread
Page 3 of 3 FirstFirst 1 2 3
Results 41 to 49 of 49

Thread: How does the compiler do with this code?

  1. Re: How does the compiler do with this code?

    Random832 wrote:
    >2006-12-19 <8764c8kaob.fld@apaflo.com>,
    >Floyd L. Davidson wrote:
    >>>>>> Actually it would be assumed to be
    >>>>>>
    >>>>>> int printf( const char * restrict format, ... );
    >>>
    >>>If, as I suspect, you don't actually believe that, it would be better to
    >>>plead temporary inanity than to claim that those words somehow mean
    >>>something that is true. [1]
    >>>
    >>>[1] Added emoticon so you don't think i'm trying to insult you

    >>
    >> The words are true. The only place where the parameter list is
    >> expected to conform to any specific prototype will be when the
    >> arguments are handed to the actual function. *THAT* is what the
    >> printf function is going to assume.

    >
    >WE ARE NOT TALKING ABOUT WHAT THE PRINTF FUNCTION WILL ASSUME!


    We are talking about why code "can be compiled, linked and run".

    >we are
    >talking about what the compiler will assume when it sees a call to
    >printf. I don't know how I can make this more clear. I don't know how it
    >was unclear in the first place. I think you're being deliberately
    >obtuse.


    What is obtuse about responding to the topic, and not igoring the
    most significant part of it?

    >I can't explain this any better than I already have.


    Yes. It still misses the point.

    --
    Floyd L. Davidson
    Ukpeagvik (Barrow, Alaska) floyd@apaflo.com

  2. Re: How does the compiler do with this code?

    2006-12-19 <87wt4oiue0.fld@apaflo.com>,
    Floyd L. Davidson wrote:
    > Random832 wrote:
    >>2006-12-19 <8764c8kaob.fld@apaflo.com>,
    >>Floyd L. Davidson wrote:
    >>>>>>> Actually it would be assumed to be
    >>>>>>>
    >>>>>>> int printf( const char * restrict format, ... );
    >>>>
    >>>>If, as I suspect, you don't actually believe that, it would be better to
    >>>>plead temporary inanity than to claim that those words somehow mean
    >>>>something that is true. [1]
    >>>>
    >>>>[1] Added emoticon so you don't think i'm trying to insult you
    >>>
    >>> The words are true. The only place where the parameter list is
    >>> expected to conform to any specific prototype will be when the
    >>> arguments are handed to the actual function. *THAT* is what the
    >>> printf function is going to assume.

    >>
    >>WE ARE NOT TALKING ABOUT WHAT THE PRINTF FUNCTION WILL ASSUME!

    >
    > We are talking about why code "can be compiled, linked and run".


    The topic drifted. You were deliberately obtuse in taking a post that
    was talking about something different though related, and wrenching it
    back to the now incorrect context.

  3. Re: How does the compiler do with this code?

    Random832 wrote:
    >2006-12-19 <87wt4oiue0.fld@apaflo.com>,
    >Floyd L. Davidson wrote:
    >> Random832 wrote:
    >>>2006-12-19 <8764c8kaob.fld@apaflo.com>,
    >>>Floyd L. Davidson wrote:
    >>>>>>>> Actually it would be assumed to be
    >>>>>>>>
    >>>>>>>> int printf( const char * restrict format, ... );
    >>>>>
    >>>>>If, as I suspect, you don't actually believe that, it would be better to
    >>>>>plead temporary inanity than to claim that those words somehow mean
    >>>>>something that is true. [1]
    >>>>>
    >>>>>[1] Added emoticon so you don't think i'm trying to insult you
    >>>>
    >>>> The words are true. The only place where the parameter list is
    >>>> expected to conform to any specific prototype will be when the
    >>>> arguments are handed to the actual function. *THAT* is what the
    >>>> printf function is going to assume.
    >>>
    >>>WE ARE NOT TALKING ABOUT WHAT THE PRINTF FUNCTION WILL ASSUME!

    >>
    >> We are talking about why code "can be compiled, linked and run".

    >
    >The topic drifted. You were deliberately obtuse in taking a post that
    >was talking about something different though related, and wrenching it
    >back to the now incorrect context.


    Please stick to appropriate commentary about the topic at hand.
    Your excuses for not understanding are of no importance at all.

    --
    Floyd L. Davidson
    Ukpeagvik (Barrow, Alaska) floyd@apaflo.com

  4. Re: How does the compiler do with this code?

    2006-12-19 <87slfcitr7.fld@apaflo.com>,
    Floyd L. Davidson wrote:
    > Please stick to appropriate commentary about the topic at hand.
    > Your excuses for not understanding are of no importance at all.


    I understood perfectly what Josef Moelle said. You either did not or
    falsely claimed not to.

  5. Re: How does the compiler do with this code?

    Random832 wrote:
    >2006-12-19 <87slfcitr7.fld@apaflo.com>,
    >Floyd L. Davidson wrote:
    >> Please stick to appropriate commentary about the topic at hand.
    >> Your excuses for not understanding are of no importance at all.

    >
    >I understood perfectly what Josef Moelle said. You either did not or
    >falsely claimed not to.


    Then try to demonstrate what you claim to underestand instead of
    posting insults.

    --
    Floyd L. Davidson
    Ukpeagvik (Barrow, Alaska) floyd@apaflo.com

  6. Re: How does the compiler do with this code?

    2006-12-19 <87k60oic90.fld@apaflo.com>,
    Floyd L. Davidson wrote:
    > Random832 wrote:
    >>2006-12-19 <87slfcitr7.fld@apaflo.com>,
    >>Floyd L. Davidson wrote:
    >>> Please stick to appropriate commentary about the topic at hand.
    >>> Your excuses for not understanding are of no importance at all.

    >>
    >>I understood perfectly what Josef Moelle said. You either did not or
    >>falsely claimed not to.

    >
    > Then try to demonstrate what you claim to underestand instead of
    > posting insults.


    When Josef Moelle wrote this:
    } IIRC the compiler assumes that the *supplied* arguments are correct and
    } that the function ...
    } > and returns an int.
    } Which is correct, in this case.
    }
    } So, effectively, the assumed prototype would be "int printf(...);"
    } (though I'm not sure if this is indeed a syntacally correct).

    He was talking about how the compiler would put in an implicit
    declaration in the code that CALLS printf. He was NOT talking about
    anything printf would assume. Everybody but you understood what he
    meant.

  7. Re: How does the compiler do with this code?

    Random832 wrote:
    >2006-12-19 <87k60oic90.fld@apaflo.com>,
    >Floyd L. Davidson wrote:
    >> Random832 wrote:
    >>>2006-12-19 <87slfcitr7.fld@apaflo.com>,
    >>>Floyd L. Davidson wrote:
    >>>> Please stick to appropriate commentary about the topic at hand.
    >>>> Your excuses for not understanding are of no importance at all.
    >>>
    >>>I understood perfectly what Josef Moelle said. You either did not or
    >>>falsely claimed not to.

    >>
    >> Then try to demonstrate what you claim to underestand instead of
    >> posting insults.


    >When Josef Moelle wrote this:
    >} IIRC the compiler assumes that the *supplied* arguments are correct and
    >} that the function ...
    >} > and returns an int.
    >} Which is correct, in this case.
    >}
    >} So, effectively, the assumed prototype would be "int printf(...);"
    >} (though I'm not sure if this is indeed a syntacally correct).
    >
    >He was talking about how the compiler would put in an implicit
    >declaration in the code that CALLS printf. He was NOT talking about
    >anything printf would assume. Everybody but you understood what he
    >meant.


    I have no way to know if Josef was or was not talking about what
    printf would assume, but my point is that it makes no difference
    because nothing *other* than what printf assumes has any
    significance. The compiler does *nothing* to or about the
    arguments provided for the call to printf (other than what are
    called "default promotions" that happen with all function calls).

    As I've said, that means that effectively the "assumed"
    prototype actually is what the definition of printf thinks it
    is, simply because the *only* action taken on any of the
    arguments, at any point in the process, is going to be taken by
    the printf code.

    The OP asked why it would compile, link and run, and *that* is
    the reason.

    Josef did want to explore various actions the compiler might
    take on argument lists. However, as I pointed out with quotes
    from the C99 ISO Standard, those actions are *not* taken when a
    ellipsis is in the prototype; hence, the lack of a prototype did
    not change how the function call is processed. Hence my
    statement above that only the code defining the printf statement
    is significant.

    Now, lets see you demonstrate some validity to the rest of your
    original statement:

    "Now, to answer the original question: On i386 linux, the
    calling convention is the same for variable arguments vs
    fixed arguments. This is not the case on other
    architectures, so the code might not work anywhere else."

    I previously asked for an example. How about even a description
    of how this could possibly be true. What "calling convention"
    are you referring to, and how would it change the results in
    *any* way, much less in a way that would cause the code to not
    work?

    I maintain that your statement is not correct. The requirements
    are that all arguments be evaluated (the order is not specified)
    and that a sequence point exists between argument evaluation and
    execution of the function. Then printf will process the first
    argument. Additional arguments will be processed as required by
    the format string of argument 1. The printf function will
    return when processing reaches the end of the format string
    regardless of whether all (or any) arguments other than the
    first have been processed.

    I see no possibility that a "calling convention" can change the
    results of a printf function.

    --
    Floyd L. Davidson
    Ukpeagvik (Barrow, Alaska) floyd@apaflo.com

  8. Re: How does the compiler do with this code?

    [comp.lang.c added - can anyone explain better than me why this is
    a problem? The original code was printf("hello\n") with no stdio.h
    included.]

    Note: "variadic" means any function that has ... in its argument list.

    2006-12-19 <874prrhokl.fld@apaflo.com>,
    Floyd L. Davidson wrote:
    > I have no way to know if Josef was or was not talking about what
    > printf would assume, but my point is that it makes no difference
    > because nothing *other* than what printf assumes has any significance.


    "What printf assumes" does not exist in a vaccuum. It is only
    significant here because of how it interacts [i.e. being the same or
    different, and whether, if it's different, it's different in important
    ways] with what the compiler assumes elsewhere.

    It's clear that its assumption is different from what the compiler is
    assuming. Our argument seems to be on whether this difference is
    important.

    > The compiler does *nothing* to or about the arguments provided for the
    > call to printf (other than what are called "default promotions" that
    > happen with all function calls).


    actually, default promotions don't happen when there is a prototype and
    it's either a non-variadic function or a fixed argument to a variadic
    function.

    > As I've said, that means that effectively the "assumed"
    > prototype actually is what the definition of printf thinks it
    > is, simply because the *only* action taken on any of the
    > arguments, at any point in the process, is going to be taken by
    > the printf code.


    Well - the compiler is converting it from source code to a series of
    machine instructions, which is pretty important since those instructions
    need to put it somewhere printf can find it. You seem to think that it
    doesn't need to know printf's prototype to do this correctly. You are
    wrong.

    > The OP asked why it would compile, link and run, and *that* is
    > the reason.


    See below.

    > Josef did want to explore various actions the compiler might
    > take on argument lists. However, as I pointed out with quotes
    > from the C99 ISO Standard, those actions are *not* taken when a
    > ellipsis is in the prototype;


    There are lots of actions which still are taken, and some which can be
    different for variadic functions. For example, commonly variadic
    arguments will be passed on the stack even on platforms that normally
    pass arguments in registers.

    You want a standard quote? S 6.5.2.2 P 6:
    } If the expression that denotes the called function has a type that
    } does not include a prototype, the integer promotions are performed on
    } each argument, and arguments that have type floatare promoted
    } todouble. These are called the default argument promotions. If the
    } number of arguments does not equal the number of parameters, the
    } behavior is undefined. IF THE FUNCTION IS DEFINED WITH A TYPE THAT
    } INCLUDES A PROTOTYPE, AND either THE PROTOTYPE ENDS WITH AN ELLIPSIS
    } (, ...) or the types of the arguments after promotion are not
    } compatible with the types of the parameters, THE BEHAVIOR IS
    } UNDEFINED. If the function is defined with a type that does not
    } include a prototype, and the types of the arguments after promotion
    } are not compatible with those of the parameters after promotion, the
    } behavior is undefined, except for the following cases:

    Emphasis mine.

    > hence, the lack of a prototype did
    > not change how the function call is processed.


    It did not change it because on i386 linux, arguments are passed the
    same way to variadic and non-variadic functions. This is not true
    elsewhere.

    > Now, lets see you demonstrate some validity to the rest of your
    > original statement:
    >
    > "Now, to answer the original question: On i386 linux, the
    > calling convention is the same for variable arguments vs
    > fixed arguments. This is not the case on other
    > architectures, so the code might not work anywhere else."
    >
    > I previously asked for an example. How about even a description
    > of how this could possibly be true. What "calling convention"
    > are you referring to, and how would it change the results in
    > *any* way, much less in a way that would cause the code to not
    > work?


    Some calling conventions pass most arguments in registers for
    non-variadic functions, but everything (even the fixed arguments) on the
    stack for variadic ones. If the compiler doesn't know that printf is
    variadic, the format string will go in a register, but printf will look
    for it on the stack.

    > I maintain that your statement is not correct. The requirements
    > are that all arguments be evaluated (the order is not specified)
    > and that a sequence point exists between argument evaluation and
    > execution of the function. Then printf will process the first
    > argument.


    Why do you believe the first argument will be put in the same place with
    the wrong prototype as it would be with the right one? It happens to be
    true on i386 Linux, but there's nothing in the standard to imply that.

    > I see no possibility that a "calling convention" can change the
    > results of a printf function.


    On i386, if non-variadic functions are normally fastcall, it will put
    the format string in a register but printf will look for it on the
    stack. If non-variadic functions are normally stdcall, the calling code
    will expect printf to clean up the arguments off of the stack, but
    printf will not do this because variadic functions cannot be stdcall
    precisely because they do not know how many arguments they have been
    passed.

    This is not the case on i386 Linux, but may be the case on other i386
    OSes; Other architectures may also use a similar calling convention to
    either stdcall or fastcall even on Linux.

    stdcall, fastcall, and cdecl are calling conventions on i386. Printf
    must be cdecl because variadic functions cannot be either of the other
    two.

  9. Re: How does the compiler do with this code?

    Random832 wrote:
    >
    > [comp.lang.c added - can anyone explain better than me why this is
    > a problem? The original code was printf("hello\n") with no stdio.h
    > included.]


    Without a prototype the compiler will assume (in C90) that the
    function returns an int, and is called with precisely one
    parameter, of type char*. In C99 you might get a warning about
    lack of prototype.

    The calling sequence to printf (at the assembly level) may be much
    different from that to some "int foo(char *);". Parameters may go
    in different registers, on a possible stack, whatever. When
    control passes to the real printf anything at all can happen. This
    all comes under the heading of "undefined behaviour".

    If is #included, the compiler has a prototype, and knows
    just how to call the function. I can't find the passage to quote,
    but the standard specifies that calling a variadic function without
    a prototype in scope is undefined behaviour.



    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.




+ Reply to Thread
Page 3 of 3 FirstFirst 1 2 3