-nostdlib 不会阻止 GCC/Clang 生成对 C 标准库函数的调用,这算正常吗?

问题描述 投票:0回答:2

来自

man gcc

-nostdlib
  Do not use the standard system startup files or libraries when linking.

这里我们看到“链接时”。这意味着

-nostdlib
不会阻止 GCC 生成对 C 标准库函数的调用。

让我们检查一下:

$ cat t35.c
#define SIZE 4096
char b[SIZE];
void _start(void)
{
  char *p = b;
  int i = SIZE;
  while(i > 0)
  {
    *p = 12;
    ++p;
    --i;
  }
}

$ arm-none-eabi-gcc t35.c -nostdlib -O2
ld.exe: cco83lvm.o: in function `_start':
t35.c:(.text+0x10): undefined reference to `memset'

在这里我们看到 ld 需要

memset
(因为 GCC 生成了
memset
)。因此,尽管用户的程序中没有
memset
,但用户仍需要提供
memset
。对于用户来说可能会感到困惑。

Clang 的故事相同:https://godbolt.org/z/jEz77fnf3

总体问题很简单:

-nostdlib
不阻止GCC/Clang生成对C标准库函数的调用是否被认为是正常的?


UPD。为了防止生成某些 C 标准库函数,有一个

-ffreestanding
选项:

断言编译目标是独立环境。这意味着 -fno-内置。独立环境是标准库可能不存在的环境,并且 程序启动不一定在“main”处。最明显的例子是操作系统内核。这相当于 -fno-hosted。

演示:

$ arm-none-eabi-gcc t35.c -nostdlib -O2 -ffreestanding
<nothing> (expected)
gcc clang llvm
2个回答
2
投票

-nostdlib 不会阻止 GCC/Clang 生成对 C 标准库函数的调用,这算是正常吗?

是的。该选项与链接和启动文件有关,而不是与优化有关。当您使用

-nostdlib
时,您通常会提供并链接到您自己的
memset
实现。


1
投票

是的,这是有记录的。

memset
和其他一些是特殊情况。

https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Standards.html#Standards

GCC 使用的大多数编译器支持例程都存在于 libgcc 中,但也有一些例外。 GCC 要求独立环境提供

memcpy
memmove
memset
memcmp
。最后,如果使用
__builtin_trap
,并且目标未实现陷阱模式,则 GCC 会发出对
abort
的调用。

© www.soinside.com 2019 - 2024. All rights reserved.