Где gcvt или gcvtf определены в исходном коде gcc?

#gcc #embedded

#gcc #встроенный

Вопрос:

Я работаю над некоторым старым исходным кодом для встроенной системы с целью m68k, и иногда я вижу массивные запросы на выделение памяти при вызове gcvtf для форматирования числа с плавающей запятой для отображения. Вероятно, я могу обойти это, написав свою собственную процедуру замены, но природа ошибки вызывает у меня большое любопытство, потому что она возникает только тогда, когда куча начинается с определенного адреса или выше, и она исчезает, если я взломаю .скрипт компоновщика ld или удалите любой набор глобальных переменных (которые помещаются перед кучей в моей карте памяти), которые составляют достаточный размер байта, чтобы куча начиналась ниже таинственного критического адреса.

Итак, я подумал, что посмотрю в исходном коде gcc версию компилятора, которую я использую (m68k-elf-gcc 3.3.2). Я загрузил то, что кажется исходным кодом для этой версии по адресу http://gcc.petsads.us/releases/gcc-3.3.2 /, но я нигде не могу найти определение для gcvt или gcvtf. Когда я ищу его, grep находит только некоторую документацию и ссылки .h, но не определение:

 $ find | xargs grep gcvt
./gcc/doc/gcc.info:     C library functions `ecvt', `fcvt' and `gcvt'.  Given va
lid
./gcc/doc/trouble.texi:library functions @code{ecvt}, @code{fcvt} and @code{gcvt
}.  Given valid
./gcc/sys-protos.h:extern char *                 gcvt(double, int, char *);
  

Итак, где эта функция фактически определена в исходном коде? Или я загрузил совершенно неправильную вещь?

Я не хочу менять этот проект, чтобы использовать самый последний gcc, из-за соображений стабильности проекта и тестирования, и, как я уже сказал, я могу обойти это, написав свою собственную процедуру форматирования, но такое поведение меня очень смущает, и оно будет терзать мой мозг, если я не найдувыясните, почему это так странно.

Ответ №1:

Уоллик прав, что это определено в библиотеке C, а не в компиляторе. Однако библиотека GNU C (почти всегда) используется только с компиляторами и дистрибутивами Linux. Ваш компилятор, будучи компилятором с «голым металлом», почти наверняка использует вместо этого библиотеку C Newlib.

Основной веб-сайт для Newlib находится здесь: http://sourceware.org/newlib /, и эта конкретная функция определена в newlib/libc/stdlib/efgcvt.c файле. Исходные коды были довольно стабильными в течение длительного времени, поэтому (если это не результат ошибки) довольно велики шансы, что текущие исходные коды не слишком отличаются от того, что использует ваш компилятор.

Как и в случае с исходным кодом GNU C, я не вижу там ничего, что, очевидно, вызвало бы эту странность, которую вы видите, но в конечном итоге все это куча оболочек вокруг базовых sprintf подпрограмм.

Комментарии:

1. Спасибо! Я нашел исходный код для версии newlib, которую я использовал (1.11.0), и что gcvt фактически вызывает функцию _dtoa_r , которая вызывает некоторые функции распределения. Я почти уверен, что странное поведение есть.

Ответ №2:

Он находится в библиотеке GNU C как glibc/misc/efgcvt.c . Чтобы избавить вас от некоторых проблем, код для функции:

 char *
__APPEND (FUNC_PREFIX, gcvt) (value, ndigit, buf)
     FLOAT_TYPE value;
     int ndigit;
     char *buf;
{
  sprintf (buf, "%.*" FLOAT_FMT_FLAG "g", MIN (ndigit, NDIGIT_MAX), value);
  return buf;
}
  

Инструкции по получению glibc приведены здесь.

Комментарии:

1. Спасибо! Естественно, это не содержит ничего, что могло бы объяснить странность распределения кучи. Ну что ж, я пока отложу свое любопытство на задний план и изучу его подробнее после завершения проекта.

2. Как я отметил в своем ответе, GNU C был бы правильным ответом для компилятора Linux, но, похоже, это простой компилятор (согласно «-elf-» в цели) и, следовательно, будет использовать Newlib.