问题
I have some C code which converts an ASCII string to a double with strtod(...). The program gets compiled for x86 (debugging), ARM and PowerPC (embedded target systems). The ARM board is actually a BeagleBoard xM running the Debian which is available for it.
I've discovered that strtod() does not convert the values correctly on the ARM / Debian system. In fact all values I tried came out as 0.000.
To demonstrate, I wrote the following very simple test program:
#include <stdio.h>
#include <stdlib.h>
int main(const int argc, const char **argv)
{
const char myString[] = "123 ";
char *myEnd1 = NULL;
char *myEnd2 = NULL;
float fValue = 0;
double dValue = 0;
dValue = atof(myString);
printf( "Using atof():\n"
" String: %s\n"
" Double: %lf\n",
myString,
dValue );
fValue = strtof(myString, &myEnd1);
dValue = strtod(myString, &myEnd2);
printf( "Using strtof() / strtod():\n"
" String: %s\n"
" Float: %f (%d)\n"
" Double: %lf (%d)\n",
myString,
fValue, (myEnd1 - myString),
dValue, (myEnd2 - myString) );
return 0;
}
All were compiled on an x86 PC running Ubuntu (actually in a virtual machine). I have cross-compiler toolchains for PowerPC and ARM compilation.
On the x86 and PowerPC systems, the output is as expected, i.e.:
Using atof():
String: 123
Double: 123.000000
Using strtof() / strtod():
String: 123
Float: 123.000000 (3)
Double: 123.000000 (3)
However, when run on the BeagleBoard, I get this:
Using atof():
String: 123
Double: 0.000000
Using strtof() / strtod():
String: 123
Float: -0.372039 (3)
Double: 0.000000 (3)
Huh??? Did I miss something stupid? Note that the "myEnd" pointers are just there to show that strtod() and strtof() did find the first non-numeric character and therefore the end of the number. They report the correct number of characters in the number in both cases (3), yet the converted value is wrong. I don't think it's a locale problem as there is no decimal point to get confused about.
EDIT:
I just recompiled the test program with the option "-static". This made the binary much bigger, of course, but now it works correctly on the target ARM platform.
I'm a bit hazy on the way libraries work. Also, I can't remember exactly how I built my cross compiler toolchain. It was probably not built from the same source as the Debian Linux actually installed on the target board.
So, does the inexplicable behavior of atof(), etc, mean a library "expected" by the dynamically-linked executable is not the same as the actual library on the system? I'm surprised that this didn't cause worse problems. We've been running this system for a year, and so far this is the only strange bug we have encountered.
来源:https://stackoverflow.com/questions/25756939/gnu-c-atof-strtof-and-strtod-fail-debian-for-beagleboard