printf() behavior

Discussion in 'C Programming' started by Mark, Aug 11, 2010.

  1. Mark

    Mark Guest

    Hello,

    this code produces warnings, but I want to understand how it's interpreted
    by compiler.

    #include <stdio.h>
    int main(void)
    {
    int b;

    b = (int)"hello"; /* 1 */

    printf("%d\n", 3.2); /* 2 */

    printf("%s\n", 1234); /* 3 */
    printf("%s\n", b); /* 4 */

    return 0;
    }

    Is the first statement legitimate? Am I right that in "1" b is evaluated to
    address of string literal?
    But I don't understand how can the compiler take the 2nd, 3rd and 4th
    expressions?

    --
    Mark
     
    Mark, Aug 11, 2010
    #1
    1. Advertising

  2. Mark

    Ian Collins Guest

    On 08/11/10 08:39 PM, Mark wrote:
    > Hello,
    >
    > this code produces warnings, but I want to understand how it's
    > interpreted by compiler.
    >
    > #include <stdio.h>
    > int main(void)
    > {
    > int b;
    >
    > b = (int)"hello"; /* 1 */
    >
    > printf("%d\n", 3.2); /* 2 */
    >
    > printf("%s\n", 1234); /* 3 */
    > printf("%s\n", b); /* 4 */
    >
    > return 0;
    > }
    >
    > Is the first statement legitimate? Am I right that in "1" b is evaluated
    > to address of string literal?


    If an address will fit in an int. This will fail on most common 64 bit
    systems.

    > But I don't understand how can the compiler take the 2nd, 3rd and 4th
    > expressions?


    The parameters following the format string in printf are just values on
    the stack (assuming there is one). They are not interpreted at compile
    time, only when the program is run. Some compilers will check the
    parameter types with the format string (gcc for example), but they are
    not required to.

    --
    Ian Collins
     
    Ian Collins, Aug 11, 2010
    #2
    1. Advertising

  3. Mark

    Jorgen Grahn Guest

    On Wed, 2010-08-11, Ian Collins wrote:
    > On 08/11/10 08:39 PM, Mark wrote:
    >> Hello,
    >>
    >> this code produces warnings, but I want to understand how it's
    >> interpreted by compiler.
    >>
    >> #include <stdio.h>
    >> int main(void)
    >> {
    >> int b;
    >>
    >> b = (int)"hello"; /* 1 */
    >>
    >> printf("%d\n", 3.2); /* 2 */
    >>
    >> printf("%s\n", 1234); /* 3 */
    >> printf("%s\n", b); /* 4 */
    >>
    >> return 0;
    >> }
    >>
    >> Is the first statement legitimate? Am I right that in "1" b is evaluated
    >> to address of string literal?

    >
    > If an address will fit in an int. This will fail on most common 64 bit
    > systems.
    >
    >> But I don't understand how can the compiler take the 2nd, 3rd and 4th
    >> expressions?

    >
    > The parameters following the format string in printf are just values on
    > the stack (assuming there is one). They are not interpreted at compile
    > time, only when the program is run. Some compilers will check the
    > parameter types with the format string (gcc for example), but they are
    > not required to.


    And if you have such a compiler, it's wise to enable that warning, and
    also enable it for home-made printf-style functions[1].

    When I enabled it on old code, plenty of bugs showed up. Some
    harmless, some definitely not. And often these things are used in
    error handling -- code which does not get exercised that often, and
    which must work.

    /Jorgen

    [1] At least with gcc, if you build your own functions on vsprintf()
    and friends, there's an __attribute__ so you can say "this
    function takes printf-style arguments beginning with #3" or
    similar.

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Aug 11, 2010
    #3
  4. On Aug 11, 11:58 am, Ian Collins <> wrote:
    >
    > If an address will fit in an int.  This will fail on most common 64 bit
    > systems.
    >

    However the campaign for 64 bit ints is working to change that
    situation.

    We've got a nice new slogan 'integers for all', making that point
    that, with world population about 6 billion, if int is 32 bits some
    people will have to do without.
     
    Malcolm McLean, Aug 11, 2010
    #4
  5. Mark

    Ian Collins Guest

    On 08/11/10 10:45 PM, Malcolm McLean wrote:
    > On Aug 11, 11:58 am, Ian Collins<> wrote:
    >>
    >> If an address will fit in an int. This will fail on most common 64 bit
    >> systems.
    >>

    > However the campaign for 64 bit ints is working to change that
    > situation.
    >
    > We've got a nice new slogan 'integers for all', making that point
    > that, with world population about 6 billion, if int is 32 bits some
    > people will have to do without.


    Just like IPv4 addresses? Although the campaign for IPv6 has a little
    more momentum than yours.

    --
    Ian Collins
     
    Ian Collins, Aug 11, 2010
    #5
  6. Mark

    Felix Palmen Guest

    * Malcolm McLean <>:
    > However the campaign for 64 bit ints is working to change that
    > situation.
    >
    > We've got a nice new slogan 'integers for all', making that point
    > that, with world population about 6 billion, if int is 32 bits some
    > people will have to do without.


    Hmm. Actually, I'm happy with NOT being a number :)

    But apart from that, I'd find it quite intuitive if an "int"
    corresponded to the CPU data register size of the platform, given that
    doesn't violate the integer type constraints of the standard...

    Regards, Felix

    --
    Felix Palmen (Zirias) + [PGP] Felix Palmen <>
    web: http://palmen-it.de/ | http://palmen-it.de/pub.txt
    my open source projects: | Fingerprint: ED9B 62D0 BE39 32F9 2488
    http://palmen-it.de/?pg=pro + 5D0C 8177 9D80 5ECF F683
     
    Felix Palmen, Aug 11, 2010
    #6
  7. In article <>,
    Malcolm McLean <> wrote:
    >On Aug 11, 11:58 am, Ian Collins <> wrote:
    >>
    >> If an address will fit in an int.  This will fail on most common 64 bit
    >> systems.
    >>

    >However the campaign for 64 bit ints is working to change that
    >situation.
    >
    >We've got a nice new slogan 'integers for all', making that point
    >that, with world population about 6 billion, if int is 32 bits some
    >people will have to do without.
    >


    (over) 7 billion.

    Do try to keep up.

    --
    "The anti-regulation business ethos is based on the charmingly naive notion
    that people will not do unspeakable things for money." - Dana Carpender

    Quoted by Paul Ciszek (pciszek at panix dot com). But what I want to know
    is why is this diet/low-carb food author doing making pithy political/economic
    statements?

    But the above quote is dead-on, because, the thing is - business in one
    breath tells us they don't need to be regulated (that they can morally
    self-regulate), then in the next breath tells us that corporations are
    amoral entities which have no obligations to anyone except their officers
    and shareholders, then in the next breath they tell us they don't need to be
    regulated (that they can morally self-regulate) ...
     
    Kenny McCormack, Aug 11, 2010
    #7
  8. Mark

    Nobody Guest

    On Wed, 11 Aug 2010 03:45:00 -0700, Malcolm McLean wrote:

    >> If an address will fit in an int.  This will fail on most common 64 bit
    >> systems.

    >
    > However the campaign for 64 bit ints is working to change that
    > situation.


    So if "int", "long" and "long long" are all going to be 64 bits, is
    "short" going to be 16 or 32 bits? Or are you going to make *that* 64 bits
    as well for good measure?

    64-bit "int" ain't gonna happen; it just breaks too much code. Even a
    64-bit "long" broke too much stuff for Microsoft's liking, hence Win64
    using a 32-bit "long".
     
    Nobody, Aug 12, 2010
    #8
  9. Mark

    Mark Guest

    "pete" <> wrote in message
    news:...
    >> Is the first statement legitimate?

    >
    > N869
    > 6.3.2.3 Pointers
    >
    > [#6] 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.
    >
    >
    >> Am I right that in "1" b is evaluated to
    >> address of string literal?

    >
    > No.
    >


    Then who is right, you or Ian Collins (see his answer up the thread) ?

    --
    Mark
     
    Mark, Aug 12, 2010
    #9
  10. Mark

    Mark Guest

    "Ian Collins" <> wrote in message
    news:...
    >> Is the first statement legitimate? Am I right that in "1" b is evaluated
    >> to address of string literal?

    >
    > If an address will fit in an int. This will fail on most common 64 bit
    > systems.


    Could you provide a snippet from the C standard sapecifying this?

    >> But I don't understand how can the compiler take the 2nd, 3rd and 4th
    >> expressions?

    >
    > The parameters following the format string in printf are just values on
    > the stack (assuming there is one). They are not interpreted at compile
    > time, only when the program is run. Some compilers will check the
    > parameter types with the format string (gcc for example), but they are not
    > required to.


    But the standard doesn't address to such terms as 'stack', 'heap' and so on,
    what does it say about these:

    printf("%d\n", 3.2);
    printf("%s\n", 1234);
    printf("%s\n", b);

    Are these under the 'implementation defined' behavior ?

    --
    Mark
     
    Mark, Aug 12, 2010
    #10
  11. "Mark" <> writes:
    [...]
    > But the standard doesn't address to such terms as 'stack', 'heap' and so on,
    > what does it say about these:
    >
    > printf("%d\n", 3.2);
    > printf("%s\n", 1234);
    > printf("%s\n", b);
    >
    > Are these under the 'implementation defined' behavior ?


    No, they're undefined behavior.

    The latest draft of the C standard is freely available at
    <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf>.
    7.19.6.1p9 says:

    If any argument is not the correct type for the corresponding
    conversion specification, the behavior is undefined.

    --
    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, Aug 12, 2010
    #11
  12. Mark

    Seebs Guest

    On 2010-08-12, Mark <> wrote:
    > But the standard doesn't address to such terms as 'stack', 'heap' and so on,
    > what does it say about these:


    > printf("%d\n", 3.2);
    > printf("%s\n", 1234);
    > printf("%s\n", b);


    > Are these under the 'implementation defined' behavior ?


    Those should all be undefined, I think.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Aug 12, 2010
    #12
  13. Mark

    Ian Collins Guest

    On 08/12/10 04:16 PM, Mark wrote:
    > "Ian Collins" <> wrote in message
    > news:...
    >>> Is the first statement legitimate? Am I right that in "1" b is evaluated
    >>> to address of string literal?

    >>
    >> If an address will fit in an int. This will fail on most common 64 bit
    >> systems.

    >
    > Could you provide a snippet from the C standard sapecifying this?


    No. But it's a general rule that quarts don't fit into pint pots.

    >>> But I don't understand how can the compiler take the 2nd, 3rd and 4th
    >>> expressions?

    >>
    >> The parameters following the format string in printf are just values
    >> on the stack (assuming there is one). They are not interpreted at
    >> compile time, only when the program is run. Some compilers will check
    >> the parameter types with the format string (gcc for example), but they
    >> are not required to.

    >
    > But the standard doesn't address to such terms as 'stack', 'heap' and so
    > on, what does it say about these:
    >
    > printf("%d\n", 3.2);
    > printf("%s\n", 1234);
    > printf("%s\n", b);
    >
    > Are these under the 'implementation defined' behavior ?


    No, they are undefined

    --
    Ian Collins
     
    Ian Collins, Aug 12, 2010
    #13
  14. On Thu, 12 Aug 2010 13:16:30 +0900, "Mark"
    <> wrote:

    snip

    >But the standard doesn't address to such terms as 'stack', 'heap' and so on,
    >what does it say about these:
    >
    >printf("%d\n", 3.2);


    The expression 3.2 has type double. %d requires the argument to be an
    int. Paragraph 7.19.6.1-9 specifically states that the behavior in
    this situation is undefined.
    >printf("%s\n", 1234);


    The expression 1234 has type int. %s requires the argument to be a
    pointer to char. Same paragraph applies.

    >printf("%s\n", b);


    The object b has type int in the original post. Same as previous
    statement.

    >
    >Are these under the 'implementation defined' behavior ?


    No, they are explicitly identified as undefined behavior.

    --
    Remove del for email
     
    Barry Schwarz, Aug 12, 2010
    #14
  15. On Thu, 12 Aug 2010 13:04:55 +0900, "Mark"
    <> wrote:

    >
    >"pete" <> wrote in message
    >news:...
    >>> Is the first statement legitimate?

    >>
    >> N869
    >> 6.3.2.3 Pointers
    >>
    >> [#6] 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.
    >>
    >>
    >>> Am I right that in "1" b is evaluated to
    >>> address of string literal?

    >>
    >> No.
    >>

    >
    >Then who is right, you or Ian Collins (see his answer up the thread) ?


    There is no conflict between the two.

    In responding to the first question, both say possibly, providing
    certain conditions are satisfied. The only difference is the
    terminology used.

    For the second question, b is an int and therefore does not hold any
    address. Only pointers hold addresses. Since the conversion from
    pointer to int is implementation-defined (6.3.2.3-6), a definitive
    answer can be had only in relation to a specific implementation.


    --
    Remove del for email
     
    Barry Schwarz, Aug 12, 2010
    #15
  16. On Aug 12, 2:29 am, Nobody <> wrote:
    >
    > So if "int", "long" and "long long" are all going to be 64 bits, is
    > "short" going to be 16 or 32 bits? Or are you going to make *that* 64 bits
    > as well for good measure?
    >

    When did you last use a short?

    It's quite rare to need such a huge number of 16 bit integers that
    memory is an issue. Lots of integers never go above 30,000, of course,
    but almost always it is better to use int.

    A C type should be thought of as a communications protocol between
    functions. The fewer protocols you have, the less likely you are to
    need to write 'glue" code switching from one type to another. Most
    software that fails fails because of the complexity of integrating all
    the different components, not because the program no longer fits in
    machine memory.
     
    Malcolm McLean, Aug 12, 2010
    #16
  17. Mark

    Ian Collins Guest

    On 08/12/10 07:20 PM, Malcolm McLean wrote:
    > On Aug 12, 2:29 am, Nobody<> wrote:
    >>
    >> So if "int", "long" and "long long" are all going to be 64 bits, is
    >> "short" going to be 16 or 32 bits? Or are you going to make *that* 64 bits
    >> as well for good measure?
    >>

    > When did you last use a short?


    About 10 minutes ago in my case (a network port number).

    > It's quite rare to need such a huge number of 16 bit integers that
    > memory is an issue. Lots of integers never go above 30,000, of course,
    > but almost always it is better to use int.
    >
    > A C type should be thought of as a communications protocol between
    > functions. The fewer protocols you have, the less likely you are to
    > need to write 'glue" code switching from one type to another. Most
    > software that fails fails because of the complexity of integrating all
    > the different components, not because the program no longer fits in
    > machine memory.


    That's why platforms have ABIs.

    This 64 bit int argument has been done to death here more than once. It
    is well established that 64 bit ints more often than not degrade
    performance on most 64 bit systems in use today. Not to mention the
    fact that 64 bit ABIs were set in stone many years ago and won't be
    changing any time soon.

    Perhaps you should wait for 128 bit systems and try again?

    --
    Ian Collins
     
    Ian Collins, Aug 12, 2010
    #17
  18. Mark

    Sjouke Burry Guest

    Malcolm McLean wrote:
    > On Aug 12, 2:29 am, Nobody <> wrote:
    >> So if "int", "long" and "long long" are all going to be 64 bits, is
    >> "short" going to be 16 or 32 bits? Or are you going to make *that* 64 bits
    >> as well for good measure?
    >>

    > When did you last use a short?


    I even used char to store.
    Example:
    #define maxstars (924710)
    static struct{
    int x,y;
    double ra;
    double decl;
    char col,t1,t2,t3;
    int filelocation;
    } s[maxstars];
     
    Sjouke Burry, Aug 12, 2010
    #18
  19. Mark

    Nobody Guest

    On Thu, 12 Aug 2010 00:20:59 -0700, Malcolm McLean wrote:

    >> So if "int", "long" and "long long" are all going to be 64 bits, is
    >> "short" going to be 16 or 32 bits? Or are you going to make *that* 64 bits
    >> as well for good measure?

    >
    > When did you last use a short?


    Yesterday.

    > It's quite rare to need such a huge number of 16 bit integers that
    > memory is an issue.


    Memory is always an issue. A lot of the code I write is in programs which
    will end up having hundreds of concurrent instances.
     
    Nobody, Aug 12, 2010
    #19
  20. "Mark" <> writes:

    > "Ian Collins" <> wrote in message
    > news:...

    <snip>
    >> If an address will fit in an int. This will fail on most common 64
    >> bit systems.

    >
    > Could you provide a snippet from the C standard sapecifying this?


    6.3.2.3 p6:

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

    and an example:

    #include <stdio.h>

    int main(void)
    {
    int x = (int)&x;
    if ((int *)x != &x)
    puts("Oh dear!");
    return 0;
    }

    This prints "Oh dear!" on my system.

    <snip>
    --
    Ben.
     
    Ben Bacarisse, Aug 13, 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. ben
    Replies:
    4
    Views:
    647
    Martin Ambuhl
    Jun 26, 2004
  2. whatluo

    (void) printf vs printf

    whatluo, May 26, 2005, in forum: C Programming
    Replies:
    29
    Views:
    1,309
  3. pai

    behavior of printf

    pai, May 1, 2006, in forum: C Programming
    Replies:
    4
    Views:
    270
    Coos Haak
    May 2, 2006
  4. azza

    printf affects following printf/s

    azza, Oct 17, 2010, in forum: C Programming
    Replies:
    0
    Views:
    452
  5. guru
    Replies:
    8
    Views:
    299
Loading...

Share This Page