我正在研究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,而且就像我说的,我可以通过编写自己的格式化例程来解决这个问题,但这种行为非常令人困惑对我来说,如果我不知道为什么它的表现如此奇怪,它会磨砺我的大脑。
答案 0 :(得分:3)
Wallyk是正确的,这是在C库而不是编译器中定义的。但是,GNU C库(几乎总是)仅用于Linux编译器和发行版。您的编译器作为“裸机”编译器,几乎肯定会使用Newlib C库。
Newlib的主要网站位于:http://sourceware.org/newlib/,此特定功能在newlib/libc/stdlib/efgcvt.c
文件中定义。源代码已经很长时间保持稳定了,所以(除非这是一个错误的结果)很可能当前的源与你的编译器使用的源不太相同。
与GNU C源代码一样,我没有看到任何明显会导致您看到这种奇怪现象的内容,但最终它们都是围绕基本sprintf
例程的一堆包装器。
答案 1 :(得分: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的指示是here。