Typecasting in C

Discussion in 'C Programming' started by andynaik, Jun 29, 2004.

  1. andynaik

    andynaik Guest

    Hi,
    Whenever we type in this code
    int main()
    {
    printf("%f",10);
    }
    we get an error. We can remove that by using #pragma directive t
    direct that to the 8087. Even after that the output is 0.00000 and no
    10.0000. Can anybody tell me why it is like that and why typecasting i
    not done in this case?
    -
    andynai
    -----------------------------------------------------------------------
    Posted via http://www.codecomments.co
    -----------------------------------------------------------------------
    andynaik, Jun 29, 2004
    #1
    1. Advertising

  2. andynaik wrote:

    > Hi,
    > Whenever we type in this code
    > int main()
    > {
    > printf("%f",10);
    > }
    > we get an error. We can remove that by using #pragma directive to
    > direct that to the 8087. Even after that the output is 0.00000 and not
    > 10.0000. Can anybody tell me why it is like that and why typecasting is
    > not done in this case??


    %f is for double, but 10 is an int.

    Rewrite as:
    #include <stdio.h>
    int main(){printf("%d",10);return 0;}
    or as:
    #include <stdio.h>
    int main(){printf("%f",10.0);return 0;}

    - Dario
    =?UTF-8?B?IkRhcmlvIChkcmlua2luZyBjb++sgGVlIGluIHRo, Jun 29, 2004
    #2
    1. Advertising

  3. andynaik

    Alex Fraser Guest

    "andynaik" <> wrote in message
    news:...
    > Whenever we type in this code
    > int main()
    > {
    > printf("%f",10);
    > }
    > we get an error. We can remove that by using #pragma directive to
    > direct that to the 8087.


    Means nothing to me (compiler specifics are off-topic here).

    > Even after that the output is 0.00000 and not 10.0000. Can anybody tell
    > me why it is like that and why typecasting is not done in this case??


    Read section 15 in the FAQ. Post back if you still have questions.
    http://www.eskimo.com/~scs/C-faq/s15.html

    Alex
    Alex Fraser, Jun 29, 2004
    #3
  4. In 'comp.lang.c', andynaik <> wrote:

    > Hi,
    > Whenever we type in this code
    > int main()
    > {
    > printf("%f",10);
    > }
    > we get an error.


    Compiling MAIN.C:
    Warning MAIN.C 4: Call to function 'printf' with no prototype
    Warning MAIN.C 5: Function should return a value
    Linking EXE\PROJ.EXE:

    This code invokes an undefined behaviour (UB). It is mandatory to supply a
    prototype when using a variadic function. Add

    #include <stdio.h>

    That said, 10 is a int. "%f" is expecting a double. If you want to printf a
    double, use 10.0, or the (double) typecast.

    Finally, some old Borland C compilers anre buggy and forget to link the
    floating point library un such a case. This little hack can help:

    #include <stdio.h>

    #ifdef __BORLANDC__
    /* The pesky "floating point formats not linked" killer hack : */
    extern unsigned _floatconvert;
    #pragma extref _floatconvert
    #endif

    int main (void)
    {
    printf ("%f\n", 10.0);

    return 0;
    }

    --
    -ed- get my email here: http://marreduspam.com/ad672570
    The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=c99
    FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
    Emmanuel Delahaye, Jun 29, 2004
    #4
  5. andynaik

    jacob navia Guest

    "Alex Fraser" <> a écrit dans le message de
    news:...
    > "andynaik" <> wrote in message
    > news:...
    > > Whenever we type in this code
    > > int main()
    > > {
    > > printf("%f",10);
    > > }
    > > we get an error. We can remove that by using #pragma directive to
    > > direct that to the 8087.

    >
    > Means nothing to me (compiler specifics are off-topic here).
    >
    > > Even after that the output is 0.00000 and not 10.0000. Can anybody tell
    > > me why it is like that and why typecasting is not done in this case??

    >
    > Read section 15 in the FAQ. Post back if you still have questions.
    > http://www.eskimo.com/~scs/C-faq/s15.html
    >
    > Alex
    >


    The FAQ should mention that some compilers DO test the arguments
    for sprintf/printf/fprintf etc for validity.

    This CAN be done. lcc-win32 does it, and other compilers too.

    For instance the above code produces
    Warning tx.c: 4 printf argument mismatch for format f. Expected double got
    int
    0 errors, 1 warnings
    jacob navia, Jun 29, 2004
    #5
  6. andynaik

    jacob navia Guest

    Some compilers DO test the arguments of printf for
    validity.
    Under lcc-win32 the above code produces:

    Warning tx.c: 4 printf argument mismatch for format f. Expected double got
    int
    0 errors, 1 warnings
    jacob navia, Jun 29, 2004
    #6
  7. andynaik

    Dan Pop Guest

    In <cbrhh5$ro2$> "jacob navia" <> writes:


    >The FAQ should mention that some compilers DO test the arguments
    >for sprintf/printf/fprintf etc for validity.
    >
    >This CAN be done.


    ONLY if the compiler can "see" the contents of the format string.
    Which is usually the case, but exceptions are not that rare either.

    At some point, gcc had the annoying habit of warning if it couldn't
    perform such a check (if enabled), because the format was not a
    string literal.

    >lcc-win32 does it, and other compilers too.


    Other compilers do a much better job than lcc-win32, when it comes to
    format string consistency checks. See below.

    >For instance the above code produces
    >Warning tx.c: 4 printf argument mismatch for format f. Expected double got
    >int
    >0 errors, 1 warnings


    OTOH, lcc-win32 silently accepts printf("%d\n", "foo"), which is very
    bad, considering the relative positions of the D and S keys on most
    keyboard layouts (i.e. it is a fairly frequent mistake to type d
    when you mean s).

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Jun 29, 2004
    #7
  8. andynaik

    jacob navia Guest

    "Dan Pop" <> a écrit dans le message de
    news:cbrqt4$29a$...
    > OTOH, lcc-win32 silently accepts printf("%d\n", "foo"), which is very
    > bad, considering the relative positions of the D and S keys on most
    > keyboard layouts (i.e. it is a fairly frequent mistake to type d
    > when you mean s).


    I pondered a long time about that one, since it is perfectly legal to
    do:

    char *p;
    ....

    printf("The address is %d\n",p);

    specially in debugging code.

    Granted, this is weird, but how to discriminate between
    legal and wrong usage?

    But maybe you are right. I added a warning when the "d" format
    is used with a pointer.

    The "x" format will NOT provoke any warnings.

    But this is at the limit of what a compiler can do.
    jacob navia, Jun 29, 2004
    #8
  9. andynaik

    Dan Pop Guest

    In <cbrvkb$bbr$> "jacob navia" <> writes:


    >"Dan Pop" <> a écrit dans le message de
    >news:cbrqt4$29a$...
    >> OTOH, lcc-win32 silently accepts printf("%d\n", "foo"), which is very
    >> bad, considering the relative positions of the D and S keys on most
    >> keyboard layouts (i.e. it is a fairly frequent mistake to type d
    >> when you mean s).

    >
    >I pondered a long time about that one, since it is perfectly legal to
    >do: ^^^^^^^^^^^^^^^^^^
    >
    >char *p;
    >...
    >
    >printf("The address is %d\n",p);


    What have you been smoking recently?

    >specially in debugging code.
    >
    >Granted, this is weird, but how to discriminate between
    >legal and wrong usage?

    ^^^^^
    Can I have a chapter and verse? When did they drop the following
    paragraph from the C standard?

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

    What is the type expected by %d? What is the type of p?
    So, the legal usage would be (int)p instead of a plain p, right?

    >But maybe you are right. I added a warning when the "d" format
    >is used with a pointer.
    >
    >The "x" format will NOT provoke any warnings.


    Which is just as bad, especially given that x is also a typo candidate
    for s.

    >But this is at the limit of what a compiler can do.


    In your humble opinion, what is the purpose of the %p conversion
    specification? Why support *anything else* for displaying pointer values?

    And if a user *really* wants to use the extra flexibility of the
    signed or unsigned integer conversion descriptors, what is preventing
    him from casting the pointer to the desired type?

    As I said in other threads, you have nothing to lose by using gcc's
    behaviour as a guide. If you can benefit from the thought many competent
    people have put into the same issue, why reinvent the wheel?

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Jun 29, 2004
    #9
  10. andynaik wrote:

    > Hi,
    > Whenever we type in this code
    > int main()
    > {
    > printf("%f",10);
    > }
    > we get an error. We can remove that by using #pragma directive to
    > direct that to the 8087. Even after that the output is 0.00000 and not
    > 10.0000. Can anybody tell me why it is like that and why typecasting is
    > not done in this case??


    Because you forgot
    #include <stdio.h>
    You also forgot to terminate the last line of output with an end-of-line
    character.

    The first mistake, omission of the prototype for a variadic function, is
    always an error. The second is an error in code designed to be
    portable, and may result in behavior you were not expecting.
    Martin Ambuhl, Jun 29, 2004
    #10
  11. jacob navia wrote:

    > "Dan Pop" <> a écrit dans le message de
    > news:cbrqt4$29a$...
    >
    >>OTOH, lcc-win32 silently accepts printf("%d\n", "foo"), which is very
    >>bad, considering the relative positions of the D and S keys on most
    >>keyboard layouts (i.e. it is a fairly frequent mistake to type d
    >>when you mean s).

    >
    >
    > I pondered a long time about that one, since it is perfectly legal to
    > do:
    >
    > char *p;
    > ...
    >
    > printf("The address is %d\n",p);


    The specifier for a pointer is "%p" and it expects a (void *) argument.
    This supposedly "legal" line should be
    printf("The address is %p\n", (void *)p);

    Please stop misleading people who might think you know what you're
    talking about.

    >
    > specially in debugging code.
    >
    > Granted, this is weird, but how to discriminate between
    > legal and wrong usage?


    You "legal" usage is _wrong_. There is no need to discriminate between
    your error and that which is wrong.
    Martin Ambuhl, Jun 29, 2004
    #11
  12. andynaik

    Dan Pop Guest

    In <> Martin Ambuhl <> writes:

    >andynaik wrote:
    >
    >> Hi,
    >> Whenever we type in this code
    >> int main()
    >> {
    >> printf("%f",10);
    >> }
    >> we get an error. We can remove that by using #pragma directive to
    >> direct that to the 8087. Even after that the output is 0.00000 and not
    >> 10.0000. Can anybody tell me why it is like that and why typecasting is
    >> not done in this case??

    >
    >Because you forgot
    >#include <stdio.h>
    >You also forgot to terminate the last line of output with an end-of-line
    >character. ^^^^^^^^^^^

    ^^^^^^^^^
    In C, it is called new-line character, even if no line follows. You must
    be confusing with the end-of-line *indicator* (which needs not be a
    character).

    >The first mistake, omission of the prototype for a variadic function, is
    >always an error. The second is an error in code designed to be
    >portable, and may result in behavior you were not expecting.


    Neither of then having anything to do with the real cause of the OP's
    problem: type mismatch in a printf call, which will continue to manifest
    even after including <stdio.h> and adding the new-line character.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Jun 29, 2004
    #12
  13. andynaik

    jacob navia Guest

    The expression

    printf("the address is: 0x%x\n",p);

    where p is some pointer appears in several million lines in
    existing code.

    The warnings can become a nuisance and people would stop
    using this feature. Personally I think warnings should be
    kept to the essential ones, warnings that would uncover a
    possible error.

    Strictly speaking you should use %p, but I have almost
    never seen it in debugging code, where this conversion is
    used.

    To the contrary of your expectations, I work to make a usable
    compiler, not one that will please the purists around c.l.c
    jacob navia, Jun 29, 2004
    #13
  14. andynaik

    Randy Howard Guest

    In article <cbrvkb$bbr$>,
    says...
    > I pondered a long time about that one, since it is perfectly legal to
    > do:
    >
    > char *p;
    > ...
    >
    > printf("The address is %d\n",p);
    >
    > specially in debugging code.


    I just lost any faith I might have had in lcc-win32. Thanks for
    the flashing warning label.
    Randy Howard, Jun 29, 2004
    #14
  15. andynaik

    Dan Pop Guest

    In <> andynaik <> writes:

    >Whenever we type in this code
    >int main()
    >{
    >printf("%f",10);
    >}
    >we get an error. We can remove that by using #pragma directive to
    >direct that to the 8087. Even after that the output is 0.00000 and not
    >10.0000. Can anybody tell me why it is like that and why typecasting is
    >not done in this case??


    Since type casting is a programming construct, it is you who have to
    explain us why you have omitted it from your program.

    If your question is why 10 wasn't *automatically converted*, which is
    something *completely* different from type casting, the answer is that
    it is located in the variable argument part of the printf call and,
    therefore, it is subject to the default argument promotions, *only*.
    In other words, although the compiler is allowed to have special
    knowledge about printf, it is not required to have such knowledge or to
    use it for fixing any mismatch between the format string and the rest
    of the arguments.

    Furthermore, because printf is a variadic function, you *must* provide
    a correct declaration for it, before calling it. So, including <stdio.h>
    is NOT optional in programs using printf and/or scanf. And a new-line
    character in the format string wouldn't hurt, either: the shell prompt
    *may* overwrite the last line of output, otherwise. Or be appended to it,
    which, even if less destructive, is still far from desirable.

    As a last remark, NOW it is the right time to get used to properly
    indenting your code.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Jun 29, 2004
    #15
  16. andynaik

    Dan Pop Guest

    In <Xns95176FE386F24hsnoservernet@212.27.42.65> Emmanuel Delahaye <> writes:

    >In 'comp.lang.c', andynaik <> wrote:
    >
    >> Hi,
    >> Whenever we type in this code
    >> int main()
    >> {
    >> printf("%f",10);
    >> }
    >> we get an error.

    >
    >Compiling MAIN.C:
    >Warning MAIN.C 4: Call to function 'printf' with no prototype
    >Warning MAIN.C 5: Function should return a value
    >Linking EXE\PROJ.EXE:


    You're sorely mistaken if you believe that compiler diagnostics *by
    themselves* prove anything at all.

    >This code invokes an undefined behaviour (UB).


    Which means that no diagnostic is required. Furthermore, even if all the
    diagnostics of your compiler are fixed, the program is still as broken
    as it was in the first place.

    >It is mandatory to supply a
    >prototype when using a variadic function. Add
    >
    >#include <stdio.h>
    >
    >That said, 10 is a int. "%f" is expecting a double. If you want to printf a
    >double, use 10.0, or the (double) typecast.


    Did you actually try to understand the OP's question? He *knows* that
    "%f" is expecting a double and he is asking why the compiler doesn't
    convert 10 to double. WHERE are you addressing this question in your
    reply?

    >Finally, some old Borland C compilers anre buggy and forget to link the
    >floating point library un such a case. This little hack can help:


    Since when are some old Borland C compilers topical to this newsgroup?
    Aren't they properly handled by the FAQ?

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Jun 29, 2004
    #16
  17. andynaik

    Dan Pop Guest

    In <cbrhh5$ro2$> "jacob navia" <> writes:


    >"Alex Fraser" <> a écrit dans le message de
    >news:...
    >> "andynaik" <> wrote in message
    >> news:...
    >> > Whenever we type in this code
    >> > int main()
    >> > {
    >> > printf("%f",10);
    >> > }
    >> > we get an error. We can remove that by using #pragma directive to
    >> > direct that to the 8087.

    >>
    >> Means nothing to me (compiler specifics are off-topic here).
    >>
    >> > Even after that the output is 0.00000 and not 10.0000. Can anybody tell
    >> > me why it is like that and why typecasting is not done in this case??

    >>
    >> Read section 15 in the FAQ. Post back if you still have questions.
    >> http://www.eskimo.com/~scs/C-faq/s15.html
    >>

    >The FAQ should mention that some compilers DO test the arguments
    >for sprintf/printf/fprintf etc for validity.


    But they *still* don't perform any automatic conversions on the arguments,
    to make them match the format string (other than the default argument
    promotions).

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Jun 29, 2004
    #17
  18. andynaik

    jacob navia Guest

    "Harti Brandt" <> a écrit dans le message de
    news:...
    > On Tue, 29 Jun 2004, jacob navia wrote:
    > That has nothing to do with purism. Ever cared to work on a machine where
    > sizeof(void *) > sizeof(int)?


    In the next implementation of lcc-win32 that will be the case (64 bit
    machine).

    In THAT environment I will issue the warning for all pointer/int
    conversions.

    In an environment where sizeof(int)==sizeof(void*) many people
    (including me) write printf("pointer value=%#x\n",p); to debug
    a piece of code. The compiler spitting you hundreds of warnings
    would only have the consequence of people IGNORING all warnings.

    lcc-win32 has several levels of warnings. After this discussion I have added
    a warning when the warning level is higher than normal for all
    implicit pointer/int conversions in the printf formats.

    It is a pity that people here like to have an atmosphere of
    aggresivity that is very boring.

    In any case this discussion was positive for me (and lcc-win32).
    I have been able to improve lcc-win32 a bit.

    Thanks for your time.
    jacob navia, Jun 29, 2004
    #18
  19. andynaik

    Dan Pop Guest

    In <cbs5ft$126$> "jacob navia" <> writes:

    >The expression
    >
    >printf("the address is: 0x%x\n",p);
    >
    >where p is some pointer appears in several million lines in
    >existing code.


    If you think that the amount of existing broken code can prove anything,
    you're sorely mistaken. The days when all the world was a 32-bit
    platform are gone...

    >The warnings can become a nuisance and people would stop
    >using this feature. Personally I think warnings should be
    >kept to the essential ones, warnings that would uncover a
    >possible error.


    In your stupidity, you don't realise that this is a genuine error, it
    just doesn't manifest on *your* platform. Try to engage your brain
    and think about platforms with 32-bit int's and 64-bit pointers
    (increasingly common since DEC released Alpha OSF/1 in 1992).

    To show you that the issue is *real* and not invented ad-hoc:

    lx64:~/tmp 11> uname -m
    x86_64
    lx64:~/tmp 12> cat test.c
    #include <stdio.h>

    int main(void)
    {
    int i;
    printf("%#x %p\n", &i, (void *)&i);
    return 0;
    }

    lx64:~/tmp 13> gcc test.c
    lx64:~/tmp 14> ./a.out
    0xbffff00c 0x7fbffff00c
    lx64:~/tmp 15> gcc -Wall test.c
    test.c: In function `main':
    test.c:6: warning: unsigned int format, pointer arg (arg 2)

    As you can see, the two values are different: %x has lost information.
    So, the people developing their code on your compiler will have a bad
    surprise when trying to use it elsewhere and you believe that you're
    doing them a favour!

    >Strictly speaking you should use %p, but I have almost
    >never seen it in debugging code, where this conversion is
    >used.
    >
    >To the contrary of your expectations, I work to make a usable
    >compiler, not one that will please the purists around c.l.c


    If you think you're doing your users any service by not diagnosing
    their genuine mistakes, simply because they *accidentally* work on
    your platform, you're even more stupid than I thought. People like you
    have no business messing with compilers and libraries.

    The FAQ *should* contain the following question: "Why should I avoid
    lcc-win32 like the plague?". But the answer would significantly increase
    its current size...

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
    Dan Pop, Jun 29, 2004
    #19
  20. andynaik

    jacob navia Guest

    "Randy Howard" <> a écrit dans le message de
    news:...
    > In article <cbrvkb$bbr$>,
    > says...
    >
    > I just lost any faith I might have had in lcc-win32. Thanks for
    > the flashing warning label.
    >


    Mr Howard

    It is a pity that people here like to have an atmosphere of
    aggresivity that is so boring.

    In any case this discussion was positive for me (and lcc-win32).
    I have been able to improve lcc-win32 a bit.

    Thanks for your time.
    jacob navia, Jun 29, 2004
    #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. =?Utf-8?B?Smlt?=

    ArrayList typecasting from binary SQL data

    =?Utf-8?B?Smlt?=, Apr 11, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    505
    Bruce Barker
    Apr 11, 2005
  2. Kapil Khosla

    Understanding Typecasting in C++

    Kapil Khosla, Jul 19, 2003, in forum: C++
    Replies:
    3
    Views:
    7,338
    John Harrison
    Jul 20, 2003
  3. Nicolay Korslund
    Replies:
    7
    Views:
    457
    Nicolay Korslund
    Sep 30, 2003
  4. venkatesh
    Replies:
    1
    Views:
    8,120
    lallous
    Dec 6, 2003
  5. Robert Street

    Advanced pointer typecasting

    Robert Street, Feb 20, 2004, in forum: C++
    Replies:
    3
    Views:
    6,937
    Robert Street
    Feb 21, 2004
Loading...

Share This Page