__atoi64 not working correctly

Discussion in 'C Programming' started by Jonathan Burd, Jan 21, 2005.

  1. Greetings everyone,

    Reading about the int64_t types added by C'99, I decided to implement
    a 64-bit version of atoi for my own library. However, for
    the test number provided, it isn't doing what it is supposed to do.
    (I used GCC/MingW32 as the compiler with C'99 enabled. Oh, and there
    is no overflow-checking in this code!) The code follows:

    #include <ctype.h>

    #ifdef __C99__
    #include <stdint.h>

    int64_t
    __atoi64 (const char *numstr)
    {
    int64_t result = 0; /* stores the resulting number */
    register int ch; /* current character */
    int sign = '+'; /* sign of the number */

    /* Try removing this and pass (const char*)NULL. ;) */
    if (NULL == numstr)
    return 0;

    /* skip leading whitespace */
    while (isspace(*numstr))
    ++numstr;

    /* get the sign. incl. '+' because it is valid! */
    sign = *numstr;
    if ('+' == sign || '-' == sign)
    ++numstr;

    /* shift digits to left by one place each time
    * and stick the new digit in.
    */
    while ( (ch = *numstr) && isdigit(ch) )
    {
    result *= 10;
    result += ch - '0';
    ++numstr;
    }

    /* return with sign. */
    return (('-' == sign) ? -result : result);
    }
    #endif /* not __C99__ */

    #ifdef TEST
    #include <stdio.h>
    int64_t __atoi64 (const char *numstr);

    int
    main (int argc, char **argv)
    {
    const char *numstr = "18726761288";

    /* Implementation-specific:
    * LONG_LONG_MAX as in limits.h = 9223372036854775807LL
    * typedef long long int64_t;
    */

    #ifdef __C99__
    printf ("%s: %lld\n", numstr, __atoi64 (numstr));
    #endif /* not __C99__ */

    return 0;
    }
    #endif /* not TEST */

    I wonder why this isn't working. Any help will be appreciated.
    Nap time. :)

    Regards,
    Jonathan.

    --
    "I'm learning to program because then I can write
    programs to do my homework faster." - Andy Anfilofieff
    Jonathan Burd, Jan 21, 2005
    #1
    1. Advertising

  2. Jonathan Burd

    jacob navia Guest

    Jonathan Burd wrote:
    > Greetings everyone,
    >
    > Reading about the int64_t types added by C'99, I decided to implement
    > a 64-bit version of atoi for my own library. However, for
    > the test number provided, it isn't doing what it is supposed to do.
    > (I used GCC/MingW32 as the compiler with C'99 enabled. Oh, and there
    > is no overflow-checking in this code!) The code follows:
    >
    > #include <ctype.h>
    >
    > #ifdef __C99__
    > #include <stdint.h>
    >
    > int64_t
    > __atoi64 (const char *numstr)
    > {
    > int64_t result = 0; /* stores the resulting number */
    > register int ch; /* current character */
    > int sign = '+'; /* sign of the number */
    >
    > /* Try removing this and pass (const char*)NULL. ;) */
    > if (NULL == numstr)
    > return 0;
    >
    > /* skip leading whitespace */
    > while (isspace(*numstr))
    > ++numstr;
    >
    > /* get the sign. incl. '+' because it is valid! */
    > sign = *numstr;
    > if ('+' == sign || '-' == sign)
    > ++numstr;
    >
    > /* shift digits to left by one place each time
    > * and stick the new digit in.
    > */
    > while ( (ch = *numstr) && isdigit(ch) )
    > {
    > result *= 10;
    > result += ch - '0';
    > ++numstr;
    > }
    >
    > /* return with sign. */
    > return (('-' == sign) ? -result : result);
    > }
    > #endif /* not __C99__ */
    >
    > #ifdef TEST
    > #include <stdio.h>
    > int64_t __atoi64 (const char *numstr);
    >
    > int
    > main (int argc, char **argv)
    > {
    > const char *numstr = "18726761288";
    >
    > /* Implementation-specific:
    > * LONG_LONG_MAX as in limits.h = 9223372036854775807LL
    > * typedef long long int64_t;
    > */
    >
    > #ifdef __C99__
    > printf ("%s: %lld\n", numstr, __atoi64 (numstr));
    > #endif /* not __C99__ */
    >
    > return 0;
    > }
    > #endif /* not TEST */
    >
    > I wonder why this isn't working. Any help will be appreciated.
    > Nap time. :)
    >
    > Regards,
    > Jonathan.
    >


    Your code works perfectly with lcc-win32.
    I get:
    18726761288: 18726761288

    lccwin32: http://www.cs.virginia.edu/~lcc-win32
    jacob navia, Jan 21, 2005
    #2
    1. Advertising

  3. jacob navia wrote:
    > Jonathan Burd wrote:

    <snip>
    >
    > Your code works perfectly with lcc-win32.
    > I get:
    > 18726761288: 18726761288
    >
    > lccwin32: http://www.cs.virginia.edu/~lcc-win32


    Intel's compiler and GCC give me this:

    18726761288: 1546892104

    Regards,
    Jonathan.

    --
    "I'm learning to program because then I can write
    programs to do my homework faster." - Andy Anfilofieff
    Jonathan Burd, Jan 21, 2005
    #3
  4. On Fri, 21 Jan 2005 13:56:20 +0530, Jonathan Burd
    <> wrote:

    > jacob navia wrote:
    >> Jonathan Burd wrote:

    > <snip>
    >>
    >> Your code works perfectly with lcc-win32.
    >> I get:
    >> 18726761288: 18726761288
    >>
    >> lccwin32: http://www.cs.virginia.edu/~lcc-win32

    >
    > Intel's compiler and GCC give me this:
    >
    > 18726761288: 1546892104


    Strange, gcc 3.0.4 (GNU/Linux / Duron 1200) and gcc 3.3.3 (Cygwin /
    WinXP / P4) both give 18726761288: 18726761288. Could it be the library
    not implementing the %lld correctly? What happens if you put the printf
    as:

    printf ("%s: %lld\n", numstr, __atoi64 (numstr) / 10);

    You should get 1872676128 for the converted answer if your function is
    working correctly.

    (Incidentally, you need to #include <stddef.h> to get a definition of
    NULL before your function uses it.)

    Chris C
    Chris Croughton, Jan 21, 2005
    #4
  5. Jonathan Burd

    jacob navia Guest

    Jonathan Burd wrote:
    > jacob navia wrote:
    >
    >> Jonathan Burd wrote:

    >
    > <snip>
    >
    >>
    >> Your code works perfectly with lcc-win32.
    >> I get:
    >> 18726761288: 18726761288
    >>
    >> lccwin32: http://www.cs.virginia.edu/~lcc-win32

    >
    >
    > Intel's compiler and GCC give me this:
    >
    > 18726761288: 1546892104
    >
    > Regards,
    > Jonathan.
    >


    This is very clear. If you make (int)18726761288LL you
    obtain 1546892104.

    Your code seems correct to me. The compilers or their
    implementation of printf are buggy.
    Note that the Intel compiler needs some extra switch to
    get into "C99" mode. See the documentation.

    If you are using gcc under windows it doesn't seem to work
    with some C99 features.

    If all else fails, download lcc-win32... It is working, at least
    what this code is concerned.

    jacob
    jacob navia, Jan 21, 2005
    #5
  6. Jonathan Burd

    jacob navia Guest

    Using linux's gcc your code works OK.

    Unmodified

    jacob
    jacob navia, Jan 21, 2005
    #6
  7. Chris Croughton wrote:
    > On Fri, 21 Jan 2005 13:56:20 +0530, Jonathan Burd

    <snip>

    > Strange, gcc 3.0.4 (GNU/Linux / Duron 1200) and gcc 3.3.3 (Cygwin /
    > WinXP / P4) both give 18726761288: 18726761288. Could it be the library
    > not implementing the %lld correctly? What happens if you put the printf
    > as:

    I have ``gcc (GCC) 3.4.1 (mingw special)" running on Windows XP / P4.

    > printf ("%s: %lld\n", numstr, __atoi64 (numstr) / 10);

    This prints ``18726761288: 1872676128". Funny.
    The earlier code still prints: ``18726761288: 1546892104".

    lcc-win32 produces the correct output: ``18726761288: 18726761288"

    > You should get 1872676128 for the converted answer if your function is
    > working correctly.
    >
    > (Incidentally, you need to #include <stddef.h> to get a definition of
    > NULL before your function uses it.)


    The code I presented is a snippet from a larger module.
    The original module has stddef.h included.
    However, I missed it when posting.

    >
    > Chris C


    I'll try updating MinGW to the latest 3.4.2 and see what happens.

    Regards,
    Jonathan.

    --
    "I'm learning to program because then I can write
    programs to do my homework faster." - Andy Anfilofieff
    Jonathan Burd, Jan 21, 2005
    #7
  8. jacob navia wrote:
    <snip>
    > This is very clear. If you make (int)18726761288LL you
    > obtain 1546892104.


    Interesting.

    > Your code seems correct to me. The compilers or their
    > implementation of printf are buggy.
    > Note that the Intel compiler needs some extra switch to
    > get into "C99" mode. See the documentation.

    <snip>

    Yes, the switch is -Qc99 and I do have it enabled.
    By the way, lcc-win32 gives the expected result.

    Regards,
    Jonathan.

    --
    "I'm learning to program because then I can write
    programs to do my homework faster." - Andy Anfilofieff
    Jonathan Burd, Jan 21, 2005
    #8
  9. On Fri, 21 Jan 2005 18:48:22 +0530, Jonathan Burd
    <> wrote:

    > Chris Croughton wrote:
    >> On Fri, 21 Jan 2005 13:56:20 +0530, Jonathan Burd

    > <snip>
    >
    >> Strange, gcc 3.0.4 (GNU/Linux / Duron 1200) and gcc 3.3.3 (Cygwin /
    >> WinXP / P4) both give 18726761288: 18726761288. Could it be the library
    >> not implementing the %lld correctly? What happens if you put the printf
    >> as:

    > I have ``gcc (GCC) 3.4.1 (mingw special)" running on Windows XP / P4.
    >
    >> printf ("%s: %lld\n", numstr, __atoi64 (numstr) / 10);

    > This prints ``18726761288: 1872676128". Funny.
    > The earlier code still prints: ``18726761288: 1546892104".


    That implies that somewhere, possibly in the library implementation of
    printf, it is being truncated to a long (1872676128 will fit in a 32 bit
    long, 1546892104 is 1872676128 truncated to 32 bits).

    You are absolutely, positively certain that you are using &lld and not
    &ld? And your function is actually being declared as returning long
    long? No insult intended, but I've done sillier things myself and they
    are surprisingly hard to spot...

    > lcc-win32 produces the correct output: ``18726761288: 18726761288"
    >
    >> You should get 1872676128 for the converted answer if your function is
    >> working correctly.


    As you do, so your function is fine it's the display of te value which
    is odd.

    >> (Incidentally, you need to #include <stddef.h> to get a definition of
    >> NULL before your function uses it.)

    >
    > The code I presented is a snippet from a larger module.
    > The original module has stddef.h included.
    > However, I missed it when posting.


    No problem. Some systems seem to define NULL in all sorts of other
    headers...

    > I'll try updating MinGW to the latest 3.4.2 and see what happens.


    I hadn't realised 3.4.2 was out...

    Chris C
    Chris Croughton, Jan 21, 2005
    #9
  10. Chris Croughton wrote:
    > On Fri, 21 Jan 2005 18:48:22 +0530, Jonathan Burd
    > <> wrote:

    <snip>

    > You are absolutely, positively certain that you are using &lld and not
    > &ld? And your function is actually being declared as returning long
    > long? No insult intended, but I've done sillier things myself and they
    > are surprisingly hard to spot...


    Yes, I checked. And then, I rechecked just to make sure my eyes are
    alright. I got a friend to see it too. He says he saw %lld and
    "long long." j/k Heh.

    <snip>

    >
    > I hadn't realised 3.4.2 was out...


    Yes, it is out. A release candidate of the setup is available as of now.

    Regards,
    Jonathan.

    --
    "I'm learning to program because then I can write
    programs to do my homework faster." - Andy Anfilofieff
    Jonathan Burd, Jan 21, 2005
    #10
  11. Jonathan Burd wrote:
    > printf ("%s: %lld\n", numstr, __atoi64 (numstr));


    And printf ("%s: %I64d\n", numstr, __atoi64 (numstr));
    prints exactly what I wanted to see. Weird.

    Regards,
    Jonathan.

    --
    "I'm learning to program because then I can write
    programs to do my homework faster." - Andy Anfilofieff
    Jonathan Burd, Jan 21, 2005
    #11
  12. Jonathan Burd

    CBFalconer Guest

    Chris Croughton wrote:
    >

    .... snip ...
    >
    > (Incidentally, you need to #include <stddef.h> to get a definition
    > of NULL before your function uses it.)


    Also in stdio.h, stdlib.h, and time.h. Any one will do.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    CBFalconer, Jan 21, 2005
    #12
  13. Jonathan Burd

    CBFalconer Guest

    Jonathan Burd wrote:
    >
    > Reading about the int64_t types added by C'99, I decided to implement
    > a 64-bit version of atoi for my own library. However, for
    > the test number provided, it isn't doing what it is supposed to do.
    > (I used GCC/MingW32 as the compiler with C'99 enabled. Oh, and there
    > is no overflow-checking in this code!) The code follows:
    >
    > #include <ctype.h>
    >
    > #ifdef __C99__
    > #include <stdint.h>
    >
    > int64_t
    > __atoi64 (const char *numstr)
    > {
    > int64_t result = 0; /* stores the resulting number */
    > register int ch; /* current character */
    > int sign = '+'; /* sign of the number */
    >
    > /* Try removing this and pass (const char*)NULL. ;) */
    > if (NULL == numstr)
    > return 0;
    >
    > /* skip leading whitespace */
    > while (isspace(*numstr))
    > ++numstr;
    >
    > /* get the sign. incl. '+' because it is valid! */
    > sign = *numstr;
    > if ('+' == sign || '-' == sign)
    > ++numstr;
    >
    > /* shift digits to left by one place each time
    > * and stick the new digit in.
    > */
    > while ( (ch = *numstr) && isdigit(ch) )
    > {
    > result *= 10;
    > result += ch - '0';
    > ++numstr;
    > }
    >
    > /* return with sign. */
    > return (('-' == sign) ? -result : result);
    > }
    > #endif /* not __C99__ */
    >
    > #ifdef TEST
    > #include <stdio.h>
    > int64_t __atoi64 (const char *numstr);
    >
    > int
    > main (int argc, char **argv)
    > {
    > const char *numstr = "18726761288";
    >
    > /* Implementation-specific:
    > * LONG_LONG_MAX as in limits.h = 9223372036854775807LL
    > * typedef long long int64_t;
    > */
    >
    > #ifdef __C99__
    > printf ("%s: %lld\n", numstr, __atoi64 (numstr));
    > #endif /* not __C99__ */
    >
    > return 0;
    > }
    > #endif /* not TEST */
    >
    > I wonder why this isn't working. Any help will be appreciated.
    > Nap time. :)


    I get:

    [1] c:\c\junk>gcc -std=c99 -D TEST junk.c
    junk.c:50: parse error before "__atoi64"
    junk.c:50: warning: type defaults to `int' in declaration of
    `__atoi64'
    junk.c:50: warning: data definition has no type or storage class

    Remember, providing int64_t is optional.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    CBFalconer, Jan 21, 2005
    #13
  14. On Fri, 21 Jan 2005 20:46:37 +0530, Jonathan Burd
    <> wrote:

    > Chris Croughton wrote:
    >> On Fri, 21 Jan 2005 18:48:22 +0530, Jonathan Burd
    >> <> wrote:

    > <snip>
    >
    >> You are absolutely, positively certain that you are using &lld and not
    >> &ld? And your function is actually being declared as returning long
    >> long? No insult intended, but I've done sillier things myself and they
    >> are surprisingly hard to spot...

    >
    > Yes, I checked. And then, I rechecked just to make sure my eyes are
    > alright. I got a friend to see it too. He says he saw %lld and
    > "long long." j/k Heh.


    If I had a pound for every time I have rechecked my own code and not
    spotted the obvious error <g>...

    Library function error seems all that's left. Oh, you could try with
    printf("%llX\n", 0x12345678901LL); and that sort of thing to see whether
    that works. Also try something like printf("%lld %d\n", 12345LL, 999);
    to see whether printf() is actually taking the long long argument and
    converting it to a long or if it's taking the argument as a long in
    which case the second field will be zero:

    #include <stdio.h>
    int main(void)
    {
    printf("%llX\n", 0x12345678901LL);
    printf("%lld %d\n", 12345LL, 999);
    printf("%ld %d\n", 12345LL, 999);
    return 0;
    }

    12345678901
    12345 999
    12345 0

    >> I hadn't realised 3.4.2 was out...

    >
    > Yes, it is out. A release candidate of the setup is available as of now.


    3.4.1 is available for Cygwin, but for some reason my upgrade didn't
    seem to work...

    Chris C
    Chris Croughton, Jan 21, 2005
    #14
  15. Jonathan Burd

    Jack Klein Guest

    On Fri, 21 Jan 2005 12:46:37 +0530, Jonathan Burd
    <> wrote in comp.lang.c:

    > Greetings everyone,
    >
    > Reading about the int64_t types added by C'99, I decided to implement
    > a 64-bit version of atoi for my own library. However, for
    > the test number provided, it isn't doing what it is supposed to do.
    > (I used GCC/MingW32 as the compiler with C'99 enabled. Oh, and there
    > is no overflow-checking in this code!) The code follows:
    >
    > #include <ctype.h>
    >
    > #ifdef __C99__
    > #include <stdint.h>
    >
    > int64_t
    > __atoi64 (const char *numstr)
    > {
    > int64_t result = 0; /* stores the resulting number */
    > register int ch; /* current character */
    > int sign = '+'; /* sign of the number */
    >
    > /* Try removing this and pass (const char*)NULL. ;) */
    > if (NULL == numstr)
    > return 0;
    >
    > /* skip leading whitespace */
    > while (isspace(*numstr))
    > ++numstr;
    >
    > /* get the sign. incl. '+' because it is valid! */
    > sign = *numstr;
    > if ('+' == sign || '-' == sign)
    > ++numstr;
    >
    > /* shift digits to left by one place each time
    > * and stick the new digit in.
    > */
    > while ( (ch = *numstr) && isdigit(ch) )
    > {
    > result *= 10;
    > result += ch - '0';
    > ++numstr;
    > }
    >
    > /* return with sign. */
    > return (('-' == sign) ? -result : result);
    > }
    > #endif /* not __C99__ */
    >
    > #ifdef TEST
    > #include <stdio.h>
    > int64_t __atoi64 (const char *numstr);
    >
    > int
    > main (int argc, char **argv)
    > {
    > const char *numstr = "18726761288";
    >
    > /* Implementation-specific:
    > * LONG_LONG_MAX as in limits.h = 9223372036854775807LL
    > * typedef long long int64_t;
    > */
    >
    > #ifdef __C99__
    > printf ("%s: %lld\n", numstr, __atoi64 (numstr));
    > #endif /* not __C99__ */
    >
    > return 0;
    > }
    > #endif /* not TEST */
    >
    > I wonder why this isn't working. Any help will be appreciated.
    > Nap time. :)
    >
    > Regards,
    > Jonathan.


    <off-topic>

    mingw is a "typical" gcc distribution, as is available for many
    platforms. It provides a tools like compiler and linker, and headers,
    but no library. It uses the platform's standard run-time library, in
    this case Microsoft's MSVC something or other DLL.

    The *printf() implementation in Microsoft's C library merely ignores
    the first 'l' in an "%lld" or other "%ll" conversion specifier, and
    treats the argument as a long, not a 32-bit value.

    You can verify this, if you have Visual C++, by building and running
    the following program:

    #include <stdio.h>


    int main(void)
    {
    __int64 i64 = 187267612;
    i64 *= 100;
    i64 += 88;
    printf("%lld\n", i64);
    return 0;
    }

    The output will be the same that you received.

    So if you want real long long support under Windows, you need an
    implementation that provides its own library and supports it. These
    include lcc-win32, Pelles C, and probably the gcc implementation that
    runs under Cygwin, but I don't know this last one for sure.

    </off-topic>

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Jan 22, 2005
    #15
  16. Jonathan Burd

    Jack Klein Guest

    On Fri, 21 Jan 2005 11:15:32 +0000, Chris Croughton
    <> wrote in comp.lang.c:

    > On Fri, 21 Jan 2005 13:56:20 +0530, Jonathan Burd
    > <> wrote:
    >
    > > jacob navia wrote:
    > >> Jonathan Burd wrote:

    > > <snip>
    > >>
    > >> Your code works perfectly with lcc-win32.
    > >> I get:
    > >> 18726761288: 18726761288
    > >>
    > >> lccwin32: http://www.cs.virginia.edu/~lcc-win32

    > >
    > > Intel's compiler and GCC give me this:
    > >
    > > 18726761288: 1546892104

    >
    > Strange, gcc 3.0.4 (GNU/Linux / Duron 1200) and gcc 3.3.3 (Cygwin /
    > WinXP / P4) both give 18726761288: 18726761288. Could it be the library
    > not implementing the %lld correctly? What happens if you put the printf
    > as:
    >
    > printf ("%s: %lld\n", numstr, __atoi64 (numstr) / 10);
    >
    > You should get 1872676128 for the converted answer if your function is
    > working correctly.
    >
    > (Incidentally, you need to #include <stddef.h> to get a definition of
    > NULL before your function uses it.)
    >
    > Chris C


    1. mingw and Intel's compiler use Microsoft's C library, and its
    printf() implementation discards one of the 'l' characters in a
    conversion specifier that starts with "%ll", perhaps in the assumption
    that the programmer made a typographical error. In any case, trying
    to convert a long long using a C90 library, and that's what it is, is
    undefined.

    2. Presumably he included <stdio.h> before calling printf(), and that
    defines NULL.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Jan 22, 2005
    #16
  17. Jonathan Burd

    Jack Klein Guest

    On Fri, 21 Jan 2005 12:34:11 +0100, jacob navia
    <> wrote in comp.lang.c:

    > Jonathan Burd wrote:
    > > jacob navia wrote:
    > >
    > >> Jonathan Burd wrote:

    > >
    > > <snip>
    > >
    > >>
    > >> Your code works perfectly with lcc-win32.
    > >> I get:
    > >> 18726761288: 18726761288
    > >>
    > >> lccwin32: http://www.cs.virginia.edu/~lcc-win32

    > >
    > >
    > > Intel's compiler and GCC give me this:
    > >
    > > 18726761288: 1546892104
    > >
    > > Regards,
    > > Jonathan.
    > >

    >
    > This is very clear. If you make (int)18726761288LL you
    > obtain 1546892104.
    >
    > Your code seems correct to me. The compilers or their
    > implementation of printf are buggy.


    Not buggy, mingw uses Microsoft's C library, the one provided in a DLL
    and used by Windows system code. And it's not buggy, it's just a C90,
    not a C99, library.

    > Note that the Intel compiler needs some extra switch to
    > get into "C99" mode. See the documentation.
    >
    > If you are using gcc under windows it doesn't seem to work
    > with some C99 features.


    I haven't used it in a while, but I seem to remember gcc running under
    Cygwin works correctly. Again, the cygwin/gcc combination provides
    its own libraries, instead of using Microsoft's.

    > If all else fails, download lcc-win32... It is working, at least
    > what this code is concerned.
    >
    > jacob


    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
    Jack Klein, Jan 22, 2005
    #17
  18. On Fri, 21 Jan 2005 23:09:27 -0600, Jack Klein
    <> wrote:

    > <off-topic>
    >
    > mingw is a "typical" gcc distribution, as is available for many
    > platforms. It provides a tools like compiler and linker, and headers,
    > but no library. It uses the platform's standard run-time library, in
    > this case Microsoft's MSVC something or other DLL.


    Aha! I knew there must be something different...

    > The *printf() implementation in Microsoft's C library merely ignores
    > the first 'l' in an "%lld" or other "%ll" conversion specifier, and
    > treats the argument as a long, not a 32-bit value.


    Why am I not surprised?

    > So if you want real long long support under Windows, you need an
    > implementation that provides its own library and supports it. These
    > include lcc-win32, Pelles C, and probably the gcc implementation that
    > runs under Cygwin, but I don't know this last one for sure.


    I can say for sure (and did in an earlier message) -- it works fine. It
    still isn't 100% compliant, though, as I recall it doesn't support %a or
    the v (maxint) length modifier for integers. And some of the new macros
    are missing from header files.

    > </off-topic>


    As someone else said recently, this means that in practice what real C
    programmers have to work to is the C89/90 standard, we can be pretty
    sure in most cases that compilers will support that (there are a few
    unfortunate programmers who still have to support things without
    function prototypes). The C99 standard is largely irrelevant from the
    point of view of writing portable code, and will be until the majority
    of the C compilers available are C99 compliant (modulo bugs, of course).

    For instance, I want to determine the 'best' floating point type for my
    application (enough significant digits with the least storage to do
    that) in the
    preprocessor. Simple, right? Something like

    #include <float.h>
    #if FLT_MANT_DIG >= 10
    typedef float my_float;
    #if DBL_MANT_DIG >= 10
    typedef double my_float;
    #if LDBL_MANT_DIG >= 10
    typedef long double my_float;
    #else
    # error No useful floating type!
    #endif

    Wrong! It's fine for C99, where the values are required to be constant
    integer expressions, but C89 says:

    Of the values in the <float.h> header, FLT_RADIX shall be a constant
    expression suitable for use in #if preprocessing directives; all
    other values need not be constant expressions. All except FLT_RADIX
    and FLT_ROUNDS have separate names for all three floating-point
    types. The floating-point model representation is provided for all
    values except FLT_ROUNDS .

    (para 2.2.4.1). So the only way to test them is to have a program which
    includes float.h and then prints out a header file containing
    appropriate definitions (for that and other reasons I have such a
    program which calculates a load of stuff about the environment -- like
    the number of bits in integer types -- and outputs a header file with
    the information because things like sizeof aren't allowed in
    preprocessor tests).

    Chris C
    Chris Croughton, Jan 22, 2005
    #18
    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?SUdvdFlvdXJEb3ROZXQ=?=

    sort not working correctly

    =?Utf-8?B?SUdvdFlvdXJEb3ROZXQ=?=, Aug 18, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    505
    =?Utf-8?B?SUdvdFlvdXJEb3ROZXQ=?=
    Aug 18, 2004
  2. Hermit Dave

    Re: dropdownlist box not working correctly

    Hermit Dave, Sep 2, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    412
    Hermit Dave
    Sep 2, 2004
  3. Stuart Palmer

    History not working correctly

    Stuart Palmer, Jun 2, 2004, in forum: HTML
    Replies:
    0
    Views:
    381
    Stuart Palmer
    Jun 2, 2004
  4. rosemm
    Replies:
    2
    Views:
    789
    Martin Honnen
    Apr 5, 2005
  5. Frederic Jolliton

    Thread not working correctly under FreeBSD

    Frederic Jolliton, Oct 23, 2003, in forum: Python
    Replies:
    4
    Views:
    357
    Frederic Jolliton
    Oct 24, 2003
Loading...

Share This Page