sscanf - проблемы на архитектуре ARM (Преобразование по формату %f не работает на ARM)

Модератор: Модераторы разделов

svary
Сообщения: 49
ОС: Linux FC-9

sscanf - проблемы на архитектуре ARM

Сообщение svary »

Кусочек кода :

Код: Выделить всё

    while ( gets(buf) != NULL ) {
    sscanf(buf, "%f", &tax);
    printf ("Преобразовано : '%s' -> %f\n", buf, tax);
    }


При компиляции gcc и выполнении на i386 все работает нормально :

Код: Выделить всё

 Преобразовано : '2.87' -> 2.870000


При компиляции для ARM (arm-gcc) и выполнении на ARM-9 получаем :

Код: Выделить всё

Преобразовано : '2.87' -> -0.000000


Кто-то может объяснить, что это за чушь и как с ней бороться ?
Спасибо сказали:
Аватара пользователя
rm_
Сообщения: 3340
Статус: It's the GNU Age
ОС: Debian

Re: sscanf - проблемы на архитектуре ARM

Сообщение rm_ »

svary
Напишите максимально простую тестовую программу (из одного .c-файла), в которой обнаруживается проблема, и приведите её целиком здесь.
Сложно помочь проверить наличие трабла, не зная, что у вас там за buf, tax, какие инклюды указаны в начале файла, и т.д.
Спасибо сказали:
svary
Сообщения: 49
ОС: Linux FC-9

Re: sscanf - проблемы на архитектуре ARM

Сообщение svary »

rm_ писал(а):
22.04.2009 09:36
svary
Напишите максимально простую тестовую программу


Собственно, то, что я привел и есть - ВСЯ программа. Ну, если более точно говорить, то когда я наткнулся на непонятное поведение разарбатываемой мной системы, то написал вот такой крохотный тест :

Код: Выделить всё

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

int main (int argc, char *srgv[]) {
    char buf[256];
    float tax;

    while ( gets(buf) != NULL ) {
    sscanf(buf, "%f", &tax);
    printf ("Преобразовано : '%s' -> %f\n", buf, tax);
    }
 }


На i386 машине компиляция и выполнение выглядит так :

Код: Выделить всё

$ cc covert.c
/tmp/cck94PjC.o: In function `main':
covert.c:(.text+0x60): warning: the `gets' function is dangerous and should not be used.
$ ./a.out
2.87
Преобразовано : '2.87' -> 2.870000
333
Преобразовано : '333' -> 333.000000
$


Про предупреждение насчет gets забудем! Хорошо ?
Далее компилирую тот же самый текст на кросс-компилере :

Код: Выделить всё

$ arm-gcc covert.c
/tmp/ccEBE1IQ.o: In function `main':
covert.c:(.text+0x20): warning: the `gets' function is dangerous and should not be used.
$


И через FTP переношу на ARM-9. После этого исполняю :

Код: Выделить всё

$ chmod 0755 a.out
$ ./a.out
2.87
Преобразовано : '2.87' -> -0.000000
333
Преобразовано : '333' -> 0.000000


Вот такие заморочки... :-( Пытался использовать

Код: Выделить всё

float strtof(const char *nptr, char **endptr);

но результат - тот же самый. По системе :

Код: Выделить всё

$ uname -a
Linux Incom-at91rm9200-brd 2.6.16 #36 Tue Mar 17 11:45:44 NOVT 2009 armv4tl unknown

$ cat /proc/cpuinfo
Processor       : ARM920Tid(wb) rev 0 (v4l)
BogoMIPS        : 89.70
Features        : swp half thumb
 . . .
$ cat /proc/meminfo
MemTotal:        29632 kB
MemFree:         10776 kB
Buffers:          8628 kB
Cached:           6348 kB
 . . .
Спасибо сказали:
Аватара пользователя
rm_
Сообщения: 3340
Статус: It's the GNU Age
ОС: Debian

Re: sscanf - проблемы на архитектуре ARM

Сообщение rm_ »

написал вот такой крохотный тест

ОК, так лучше, если проблема не решится, попробую сегодня вечером тоже запустить его на ARM'е (немного другом).
На amd64 конвертит нормально.
Спасибо сказали:
mikluxo
Сообщения: 283
ОС: Slackware 12.2

Re: sscanf - проблемы на архитектуре ARM

Сообщение mikluxo »

Автор посмотрите ман:
BUGS
Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.

Попробуйте вместо gets поставить fgets и посмотреть на выполнение, мне кажется именно она считывает лишний символ(или еще что) в результате чего, после конвертирования получается 0, или попробуйте не считывая просто переконвертировать строку в ковычках.
Ich weiss, dass ich nichts weiss, aber wissen Sie es auch?
Завистники на что не взглянут,
подымут вечно лай,
А ты себе своей дорогою ступай,
Полают, да отстанут. Крылов
Спасибо сказали:
Аватара пользователя
rm_
Сообщения: 3340
Статус: It's the GNU Age
ОС: Debian

Re: sscanf - проблемы на архитектуре ARM

Сообщение rm_ »

Код: Выделить всё

$ ./a.out
1.1
Преобразовано : '1.1' -> 1.100000
2.783
Преобразовано : '2.783' -> 2.783000
$ cat /proc/cpuinfo
Processor    : XScale-PXA270 rev 7 (v5l)
BogoMIPS    : 518.14
Features    : swp half thumb fastmult edsp iwmmxt
CPU implementer    : 0x69
CPU architecture: 5TE
CPU variant    : 0x0
CPU part    : 0x411
CPU revision    : 7
Cache type    : undefined 5
Cache clean    : undefined 5
Cache lockdown    : undefined 5
Cache format    : Harvard
I size        : 32768
I assoc        : 32
I line length    : 32
I sets        : 32
D size        : 32768
D assoc        : 32
D line length    : 32
D sets        : 32

Hardware    : HTC Universal
Revision    : 0000
Serial        : 0000000000000000

Так что дело наверняка не в ARM'e как таковом. Может быть, в версии компилятора и библиотек? У меня:

Код: Выделить всё

$ dpkg -l gcc libc6-dev libc6
...
ii  gcc            4:4.3.2-2      The GNU C compiler
ii  libc6          2.7-18         GNU C Library: Shared libraries
ii  libc6-dev      2.7-18         GNU C Library: Development Libraries and Hea
Спасибо сказали:
svary
Сообщения: 49
ОС: Linux FC-9

Re: sscanf - проблемы на архитектуре ARM

Сообщение svary »

Может быть, в версии компилятора и библиотек?


У меня Fedora, а не Debian, поэтому немножко иначе :

Код: Выделить всё

$ rpm -qi gcc
Name        : gcc                          Relocations: (not relocatable)
Version     : 4.3.2                             Vendor: Fedora Project
 . . .

$ rpm -qi libc6-dev
пакет libc6-dev не установлен

$ rpm -qi libc6
пакет libc6 не установлен


С библиотеками я что-то не очень понял. У меня установлено :

Код: Выделить всё

$ rpm -qi glibc
Name        : glibc                        Relocations: (not relocatable)
Version     : 2.9                               Vendor: Fedora Project
 . . .

$ rpm -qi glibc-devel
Name        : glibc-devel                  Relocations: (not relocatable)
Version     : 2.9                               Vendor: Fedora Project
   .  .  .

А если посмотреть внимательнее, то получим, что 2.9 - это и есть шестерка :

Код: Выделить всё

$ rpm -ql glibc
 . . .
/lib/libc-2.9.so
/lib/libc.so.6
 . . .
$ ls -l /lib/libc.so.6
lrwxrwxrwx 1 root root 11 Мар 12 15:14 /lib/libc.so.6 -> libc-2.9.so


На ARM-е все то же самое, только версия библиотеки - 2.3. Я подозреваю, что проблемы в ядре. Тот девайс, для которого пишу программу, он с ядром хоть и 2.6, но собранном из исходов и вполне может быть, что мы туда чего-то "недовложили"... :-( Причем, сама по себе, плавающая арифметика работает. Вот крохотный тест :

Код: Выделить всё

int main (int argc, char *srgv[]) {
    float tax;
    int j;

    tax = 2.5;
    j = 2.0 * tax;
    printf("j=%d\n", j);
 }

$ ./a.out
j=5
$

Короче - не могу понять, с какой стороны за это дело браться... :-(
Спасибо сказали: