Floating point support not loaded

Discussion in 'C Programming' started by lolzy@live.nl, Mar 24, 2012.

  1. Guest

    Good day!


    When I use this function, I get the following output:

    runtime error R6002
    - floating point support not loaded


    Note:
    - safeMalloc() is a safe function with error handling.
    - sizeof(string) >= sizeof(buf) (so no overflows)



    /*
    * Encode a string according to http://tools.ietf.org/html/rfc3986#section-2.1.
    */
    void urlEncode(char *string)
    {
    int i = 0;
    char *buf = safeMalloc(((strlen(string) * 3) + 1) * sizeof(char));
    buf[0] = '\0';

    while (string != '\0')
    {
    if (isalnum(string) || string == '-' || string == '_' ||
    string == '.' || string == '~' || string == ' ')
    {
    if (string == ' ') string = '+';
    sprintf(buf, "%s%c", buf, string);
    }
    else
    {
    sprintf(buf, "%s%%%.2X", buf, string);
    }

    ++i;
    }

    strcpy(string, buf);
    free(buf);
    }


    Yours Sincerely,
    Jori.
    , Mar 24, 2012
    #1
    1. Advertising

  2. בת×ריך ×™×•× ×©×‘×ª,24 במרס 2012 10:04:44 UTC, מ×ת :
    >
    > When I use this function, I get the following output:
    >
    > runtime error R6002
    > - floating point support not loaded
    >
    > [function, including]
    > sprintf(buf, "%s%%%.2X", buf, string);
    >

    Probably sprintf automatically drags in the code to covert the %f and %g specifiers. The compiler isn't smart enough to realise they aren't actually needed. Since you don't have floating point enabled, it complains.

    --
    Basic Algorithms - how to implement the math library from scratch
    http://www.malcolmmclean.site11.com/www
    Malcolm McLean, Mar 24, 2012
    #2
    1. Advertising

  3. Eric Sosman Guest

    On 3/24/2012 6:04 AM, wrote:
    > Good day!
    >
    >
    > When I use this function, I get the following output:
    >
    > runtime error R6002
    > - floating point support not loaded


    This sounds very much like Question 14.13 on the comp.lang.c
    Frequently Asked Questions (FAQ) page at <http://www.c-faq.com/>,
    although it may be different in detail. That's a reasonable place
    to start, anyhow.

    Your code has other problems, though. I've spotted a few:

    >
    > Note:
    > - safeMalloc() is a safe function with error handling.
    > - sizeof(string)>= sizeof(buf) (so no overflows)
    >
    >
    >
    > /*
    > * Encode a string according to http://tools.ietf.org/html/rfc3986#section-2.1.
    > */
    > void urlEncode(char *string)
    > {
    > int i = 0;
    > char *buf = safeMalloc(((strlen(string) * 3) + 1) * sizeof(char));
    > buf[0] = '\0';


    You probably won't need this (see below).

    > while (string != '\0')
    > {
    > if (isalnum(string) || string == '-' || string == '_' ||
    > string == '.' || string == '~' || string == ' ')


    Use `isalnum( (unsigned char)string )' as the first part of
    the test. Otherwise you're likely to get into trouble when dealing
    with "exotic" characters on systems where `char' is signed.

    > {
    > if (string == ' ') string = '+';


    It might have been smoother to treat the space character as a
    case of its own. As things stand, you're making a special test to
    include it in this case, and then making another test to give it
    special treatment. (General principle: If you find yourself writing
    two tests for the same condition, consider whether rearranging to
    eliminate one test would lead to simpler code.)

    > sprintf(buf, "%s%c", buf, string);


    Here's where the really serious trouble begins: "If copying
    takes place between objects that overlap, the behavior is undefined"
    (section 7.21.6.6 paragraph 2 of the C Standard). In this instance,
    the code tries to copy from `buf' to `buf', and since `buf' clearly
    overlaps itself there's no telling what might happen. One remedy
    might be to append the new material without copying the old:

    sprintf(buf + strlen(buf), "%c", string);

    To my taste, though, that's a lot of machinery just to copy a single
    character from one place to another! If I were writing the code, I
    think I'd maintain a second pointer like `char *end;' whose job is
    to point just after the last character deposited in `buf'. It would
    start out equal to `buf' and would advance as characters were
    appended. Using such a pointer, you could replace this line with

    *end++ = string;

    .... which I think you'll agree is a much "lighter-weight" solution.
    Note that this copies only one character, meaning that `buf' will
    not have a '\0' at the end -- but that's all right, because you
    don't need `buf' to hold a well-formed string until you've finished
    converting all of `string'.

    > }
    > else
    > {
    > sprintf(buf, "%s%%%.2X", buf, string);


    Same problem with overlap, with similar solutions. In this
    case it's probably easier to let sprintf() take care of the hex
    conversion, so you'd have

    end += sprintf(end, "%%%.2X", string);

    > }
    >
    > ++i;
    > }


    If you're using the `end' pointer as I suggest, at this point
    you need to supply a '\0' to ensure a well-formed string before
    calling strcpy() on it:

    *end = '\0';

    > strcpy(string, buf);
    > free(buf);
    > }



    --
    Eric Sosman
    d
    Eric Sosman, Mar 24, 2012
    #3
  4. Guest

    On 24 mrt, 13:05, Eric Sosman <> wrote:
    > On 3/24/2012 6:04 AM, wrote:
    >
    > > Good day!

    >
    > > When I use this function, I get the following output:

    >
    > > runtime error R6002
    > > - floating point support not loaded

    >
    >      This sounds very much like Question 14.13 on the comp.lang.c
    > Frequently Asked Questions (FAQ) page at <http://www.c-faq.com/>,
    > although it may be different in detail.  That's a reasonable place
    > to start, anyhow.
    >
    >      Your code has other problems, though.  I've spotted a few:
    >
    >
    >
    > > Note:
    > > - safeMalloc() is a safe function with error handling.
    > > - sizeof(string)>= sizeof(buf) (so no overflows)

    >
    > > /*
    > >   * Encode a string according tohttp://tools.ietf.org/html/rfc3986#section-2.1.
    > > */
    > > void urlEncode(char *string)
    > > {
    > >    int i = 0;
    > >    char *buf = safeMalloc(((strlen(string) * 3) + 1) * sizeof(char));
    > > buf[0] = '\0';

    >
    >      You probably won't need this (see below).
    >
    > >    while (string != '\0')
    > >    {
    > >            if (isalnum(string) || string == '-' || string == '_' ||
    > > string == '.' || string == '~' || string == ' ')

    >
    >      Use `isalnum( (unsigned char)string )' as the first part of
    > the test.  Otherwise you're likely to get into trouble when dealing
    > with "exotic" characters on systems where `char' is signed.
    >
    > >            {
    > >                    if (string == ' ') string = '+';

    >
    >      It might have been smoother to treat the space character as a
    > case of its own.  As things stand, you're making a special test to
    > include it in this case, and then making another test to give it
    > special treatment.  (General principle: If you find yourself writing
    > two tests for the same condition, consider whether rearranging to
    > eliminate one test would lead to simpler code.)
    >
    > >                    sprintf(buf, "%s%c", buf, string);

    >
    >      Here's where the really serious trouble begins: "If copying
    > takes place between objects that overlap, the behavior is undefined"
    > (section 7.21.6.6 paragraph 2 of the C Standard).  In this instance,
    > the code tries to copy from `buf' to `buf', and since `buf' clearly
    > overlaps itself there's no telling what might happen.  One remedy
    > might be to append the new material without copying the old:
    >
    >         sprintf(buf + strlen(buf), "%c", string);
    >
    > To my taste, though, that's a lot of machinery just to copy a single
    > character from one place to another!  If I were writing the code, I
    > think I'd maintain a second pointer like `char *end;' whose job is
    > to point just after the last character deposited in `buf'.  It would
    > start out equal to `buf' and would advance as characters were
    > appended.  Using such a pointer, you could replace this line with
    >
    >         *end++ = string;
    >
    > ... which I think you'll agree is a much "lighter-weight" solution.
    > Note that this copies only one character, meaning that `buf' will
    > not have a '\0' at the end -- but that's all right, because you
    > don't need `buf' to hold a well-formed string until you've finished
    > converting all of `string'.
    >
    > >            }
    > >            else
    > >            {
    > >                    sprintf(buf, "%s%%%.2X", buf, string);

    >
    >      Same problem with overlap, with similar solutions.  In this
    > case it's probably easier to let sprintf() take care of the hex
    > conversion, so you'd have
    >
    >         end += sprintf(end, "%%%.2X", string);
    >
    > >            }

    >
    > >            ++i;
    > >    }

    >
    >      If you're using the `end' pointer as I suggest, at this point
    > you need to supply a '\0' to ensure a well-formed string before
    > calling strcpy() on it:
    >
    >         *end = '\0';
    >
    > >    strcpy(string, buf);
    > >    free(buf);
    > > }

    >
    > --
    > Eric Sosman
    >


    I totally agree with you. I wasn't finished optimizing the code
    yet :). But I didn't knew of the 7.21.6.6.

    Thanks a lot.
    , Mar 24, 2012
    #4
  5. Guest

    /*
    * Encode a string according to http://tools.ietf.org/html/rfc3986#section-2.1.
    */
    void urlEncode(char *string)
    {
    float test = sqrt(9);
    int i = 0;
    char *buf = KhSafeMalloc(((strlen(string) * 3) + 1) * sizeof(char)),
    *end = buf;

    while (string != '\0')
    {
    if ((unsigned char) isalnum(string) || string == '-' ||
    string == '_' || string == '.' || string == '~')
    *end++ = string;
    else if (string == ' ')
    *end++ = '+';
    else
    end += sprintf(end, "%%%.2X", string);

    ++i;
    }

    *end = '\0';
    strcpy(string, buf);
    free(buf);
    }


    'float test = sqrt(9)' did the trick :)
    , Mar 24, 2012
    #5
  6. Eric Sosman Guest

    On 3/24/2012 1:51 PM, wrote:
    > /*
    > * Encode a string according to http://tools.ietf.org/html/rfc3986#section-2.1.
    > */
    > void urlEncode(char *string)
    > {
    > float test = sqrt(9);


    I guess this ensures the presence of floating-point support.
    Seems like there ought to be a more direct way, though: possibly
    a compiler or linker command-line option or something of that kind.

    > int i = 0;
    > char *buf = KhSafeMalloc(((strlen(string) * 3) + 1) * sizeof(char)),
    > *end = buf;
    >
    > while (string != '\0')
    > {
    > if ((unsigned char) isalnum(string) || string == '-' ||


    Not quite: `isalnum((unsigned char)string)' is what you want.

    Here's the deal: In the dim mists of prehistory, the people who
    invented what has become <ctype.h> thought it would be a good idea if
    the functions could be applied not only to `char' values, but to any
    value one might read from an input stream. A `char' value read by
    the getc() function or any of its relatives is always non-negative,
    making it easy to distinguish actual input from the special, negative
    EOF value that means "no input: finished or failed." So that's what
    the isxxx() functions require for their arguments: Either the negative
    EOF value or a non-negative `char' value.

    There are several problems with this scheme. The one that's of
    concern here is that `char' itself is unsigned on some systems, but
    signed on others. The "basic execution character set" values are
    all non-negative (6.2.5p3), but additional characters may be positive
    or negative: Try a few like âĕïòú and you might see negative values.
    To avoid this issue, getc() and friends return actual characters as
    the values they would have if converted to `unsigned char' and then
    stored in an `int'.

    But if you pluck a `char' value from a string, you might wind
    up with a negative value (for some characters on some systems).
    If you feed this value to isxxx() or toxxx() you are asking for
    trouble: The *only* valid negative argument value for these functions
    is EOF, and the behavior is undefined if you pass some other negative
    value (7.4p1). On many systems these "functions" are implemented as
    macros that use the argument as an array index, and you'll wind up
    indexing into the never-never-land that lies before the array, with
    unpredictable consequences. It's unfortunate, but in the name of
    "backward compatibility" it's too late to change.

    > string == '_' || string == '.' || string == '~')
    > *end++ = string;
    > else if (string == ' ')
    > *end++ = '+';
    > else
    > end += sprintf(end, "%%%.2X", string);
    >
    > ++i;
    > }
    >
    > *end = '\0';
    > strcpy(string, buf);
    > free(buf);
    > }
    >
    >
    > 'float test = sqrt(9)' did the trick :)



    --
    Eric Sosman
    d
    Eric Sosman, Mar 24, 2012
    #6
  7. writes:
    > /*
    > * Encode a string according to http://tools.ietf.org/html/rfc3986#section-2.1.
    > */
    > void urlEncode(char *string)
    > {
    > float test = sqrt(9);
    > int i = 0;
    > char *buf = KhSafeMalloc(((strlen(string) * 3) + 1) * sizeof(char)),
    > *end = buf;
    >
    > while (string != '\0')
    > {
    > if ((unsigned char) isalnum(string) || string == '-' ||
    > string == '_' || string == '.' || string == '~')
    > *end++ = string;
    > else if (string == ' ')
    > *end++ = '+';
    > else
    > end += sprintf(end, "%%%.2X", string);
    >
    > ++i;
    > }
    >
    > *end = '\0';
    > strcpy(string, buf);
    > free(buf);
    > }
    >
    >
    > 'float test = sqrt(9)' did the trick :)


    It's likely that you don't actually have to *execute* the call to the
    sqrt() function to cause floating point support to be loaded. Try
    something like:

    float test = 0 ? sqrt(9) : 0;

    or perhaps even:

    sqrt;

    The latter is not a call to sqrt; it's an expression that evaluates to
    the address of the sqrt function. Since the result is discarded, it
    shouldn't generate any actual code, but it might force the compiler to
    load the floating-point code anyway.

    In both cases, a sufficiently clever compiler can recognize that the
    code has no effect and eliminate it -- but your compiler is
    insufficiently clever either to load the floating-point code or to
    recognize that it doesn't need it.

    Of course you should have "#include <math.h>" if you refer to the sqrt
    function.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Mar 24, 2012
    #7
  8. On 24.03.2012 22:34, Keith Thompson wrote:
    > writes:
    >> /*
    >> * Encode a string according to http://tools.ietf.org/html/rfc3986#section-2.1.
    >> */
    >> void urlEncode(char *string)
    >> {
    >> float test = sqrt(9);
    >> int i = 0;
    >> char *buf = KhSafeMalloc(((strlen(string) * 3) + 1) * sizeof(char)),
    >> *end = buf;
    >>
    >> while (string != '\0')
    >> {
    >> if ((unsigned char) isalnum(string) || string == '-' ||
    >> string == '_' || string == '.' || string == '~')
    >> *end++ = string;
    >> else if (string == ' ')
    >> *end++ = '+';
    >> else
    >> end += sprintf(end, "%%%.2X", string);
    >>
    >> ++i;
    >> }
    >>
    >> *end = '\0';
    >> strcpy(string, buf);
    >> free(buf);
    >> }
    >>
    >>
    >> 'float test = sqrt(9)' did the trick :)

    >
    > It's likely that you don't actually have to *execute* the call to the
    > sqrt() function to cause floating point support to be loaded. Try
    > something like:
    >
    > float test = 0 ? sqrt(9) : 0;
    >
    > or perhaps even:
    >
    > sqrt;
    >
    > The latter is not a call to sqrt; it's an expression that evaluates to
    > the address of the sqrt function. Since the result is discarded, it
    > shouldn't generate any actual code, but it might force the compiler to
    > load the floating-point code anyway.
    >


    Ever heard of dead code elimination? It's a very basic optimization that
    would remove the reference to sqrt() and therefore the need to link
    against libm (or whatever that system's equal of it is).

    > In both cases, a sufficiently clever compiler can recognize that the
    > code has no effect and eliminate it -- but your compiler is
    > insufficiently clever either to load the floating-point code or to
    > recognize that it doesn't need it.
    >


    That's another can of worms. The way I see it, the designers of that
    system's *scanf() did a bad job, because they depend on floating-point
    support at runtime, but don't tell anyone during link time. My take on
    it is that the compiler tries linking without libm and if that doesn't
    work, tries it with libm. Maybe even something bigger, like linking
    against nothing but libc, writing down all the "undefined reference"
    errors and looking up the symbols in the libraries directory, then
    linking in all the necessary libraries. Basically what you would get
    with GNU ld and zsh and

    ld -I/lib/ld-linux.so.2 -o output *.o --as-needed {/usr,}/lib/**/*.so

    But somehow those guys wrote scanf() to not directly reference libm, so
    this code doesn't see that it should include libm.

    See the problem? The compiler can have all optimizations in the world,
    here the linker and library conspire together to not make it work. If
    you ask me, switch compilers!

    > Of course you should have "#include <math.h>" if you refer to the sqrt
    > function.
    >


    That's true, too.

    Ciao,
    Markus
    Markus Wichmann, Mar 26, 2012
    #8
  9. James Kuyper Guest

    On 03/26/2012 04:29 AM, Markus Wichmann wrote:
    > On 24.03.2012 22:34, Keith Thompson wrote:

    ....
    >> It's likely that you don't actually have to *execute* the call to the
    >> sqrt() function to cause floating point support to be loaded. Try
    >> something like:
    >>
    >> float test = 0 ? sqrt(9) : 0;
    >>
    >> or perhaps even:
    >>
    >> sqrt;
    >>
    >> The latter is not a call to sqrt; it's an expression that evaluates to
    >> the address of the sqrt function. Since the result is discarded, it
    >> shouldn't generate any actual code, but it might force the compiler to
    >> load the floating-point code anyway.
    >>

    >
    > Ever heard of dead code elimination? It's a very basic optimization that
    > would remove the reference to sqrt() and therefore the need to link
    > against libm (or whatever that system's equal of it is).


    I'm sure he has, since he mentions it in the very next line of his that
    you quoted. The use of sqrt is just a trick that shouldn't be necessary
    when using a fully conforming implementation of C. If this
    implementation requires special command line options to load the
    floating point math support needed by printf(), then it isn't fully
    conforming without those options selected.

    >> In both cases, a sufficiently clever compiler can recognize that the
    >> code has no effect and eliminate it -- but your compiler is
    >> insufficiently clever either to load the floating-point code or to
    >> recognize that it doesn't need it.
    >>

    >
    > That's another can of worms. The way I see it, the designers of that
    > system's *scanf() did a bad job, because they depend on floating-point
    > support at runtime, but don't tell anyone during link time. My take on
    > it is that the compiler tries linking without libm and if that doesn't
    > work, tries it with libm. ...


    I presume that one of those two "libm"s was supposed to be something else?
    --
    James Kuyper
    James Kuyper, Mar 26, 2012
    #9
  10. On 26.03.2012 12:48, James Kuyper wrote:
    > On 03/26/2012 04:29 AM, Markus Wichmann wrote:
    >> That's another can of worms. The way I see it, the designers of that
    >> system's *scanf() did a bad job, because they depend on floating-point
    >> support at runtime, but don't tell anyone during link time. My take on
    >> it is that the compiler tries linking without libm and if that doesn't
    >> work, tries it with libm. ...

    >
    > I presume that one of those two "libm"s was supposed to be something else?


    No. Perhaps I should add some emphasis: The linker first tries to link
    _without_ libm. Then, if that doesn't work, the link is tried again,
    this time _with_ libm.

    Note that that is one possible explanation for the weird behaviour the
    OP is experiencing. The real reason may be something entirely different.
    Still, what I meant by the above is that the compiler can't be faulted
    for mistakes of linker and library.

    Ciao,
    Markus
    Markus Wichmann, Mar 26, 2012
    #10
  11. James Kuyper Guest

    On 03/26/2012 07:31 AM, Markus Wichmann wrote:
    > On 26.03.2012 12:48, James Kuyper wrote:
    >> On 03/26/2012 04:29 AM, Markus Wichmann wrote:
    >>> That's another can of worms. The way I see it, the designers of that
    >>> system's *scanf() did a bad job, because they depend on floating-point
    >>> support at runtime, but don't tell anyone during link time. My take on
    >>> it is that the compiler tries linking without libm and if that doesn't
    >>> work, tries it with libm. ...

    >>
    >> I presume that one of those two "libm"s was supposed to be something else?

    >
    > No. Perhaps I should add some emphasis: The linker first tries to link
    > _without_ libm. Then, if that doesn't work, the link is tried again,
    > this time _with_ libm.


    Sorry - I somehow managed to misread "without" as "with".

    > Note that that is one possible explanation for the weird behaviour the
    > OP is experiencing. ...


    It's a possible linkage strategy, but if it is followed, then a failure
    to find needed symbols during the first (without libm) pass shouldn't
    cause a warning message, much less an error message accompanied by a
    linkage failure. That should only occur if the symbols are not found on
    the second (with libm) pass.

    >... The real reason may be something entirely different.
    > Still, what I meant by the above is that the compiler can't be faulted
    > for mistakes of linker and library.


    Producing a fatal linkage error before having attempted to link to all
    of the libraries it's supposed to be searching is a pretty severe
    mistake for the linker to make. In my experience (which is, admittedly,
    based on a relatively small number of different implementations of C),
    the compiler normally tells the linker what libraries to search for; the
    linker just followings those instructions - in which case it is indeed
    the compiler's fault for issuing bad instructions.
    --
    James Kuyper
    James Kuyper, Mar 26, 2012
    #11
    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. H aka N
    Replies:
    15
    Views:
    15,647
    Ben Jones
    Mar 2, 2006
  2. Motaz Saad
    Replies:
    7
    Views:
    6,483
  3. Replies:
    4
    Views:
    1,284
    Default User
    Feb 22, 2006
  4. Saraswati lakki
    Replies:
    0
    Views:
    1,322
    Saraswati lakki
    Jan 6, 2012
  5. teeshift
    Replies:
    2
    Views:
    253
    Chris Pearl
    Dec 1, 2006
Loading...

Share This Page