vfscanf.c 警告:scanf 函数会增加数千字节的膨胀

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

我在使用 Dietlibc 时收到此警告消息。是不是因为dietlibc版本的原因。我正在使用饮食 0.33

我无法解决此警告,请帮助我

c linux warnings
2个回答
0
投票

您的程序需要将 scanf 库函数添加到您的目标代码中。这要么是因为您使用 sscanf 或其他此类函数,要么是您调用的函数又需要 scanf 函数。

scanf(和 printf)库因庞大而闻名。它们需要解码(和编码)字符串、十六进制和浮点等的所有函数。仅仅因为使用单个 scanf 函数,您最终可能会将 2k 程序扩展到 20k。

该警告告诉您,您的程序可能比其他情况占用更多空间,因为您需要使用 scanf 库。

编辑:

库是目标文件的集合。链接器添加程序所需的任何目标文件。它不能包含目标文件的一部分;要么全有,要么全无。因为 vscanf 包含在 Dietlib 的 libstdio.o 中,所以您使用的任何 stdio 函数都会引入 vsscanf。

参见 https://github.com/hchunhui/dietlibc/blob/master/Makefile :

LIBSTDIOOBJ=$(patsubst libstdio/%.c,$(OBJDIR)/%.o,$(wildcard libstdio/*.c))

DIETLIBC_OBJ = $(OBJDIR)/unified.o \
$(SYSCALLOBJ) $(LIBOBJ) $(LIBSTDIOOBJ) $(LIBUGLYOBJ) \
$(LIBCRUFTOBJ) $(LIBCRYPTOBJ) $(LIBSHELLOBJ) $(LIBREGEXOBJ) \
$(OBJDIR)/__longjmp.o $(OBJDIR)/setjmp.o \

$(OBJDIR)/dietlibc.a: $(DIETLIBC_OBJ) $(OBJDIR)/start.o
    $(CROSS)ar cru $@ $(DIETLIBC_OBJ)

并注意 vsscanf 位于 libstdio 目录中。

就我个人而言,我会尝试将 scanf 和 printf 函数放在单独的目标文件中,因为它们太大了。我还看到一些库附带了两个版本的 scanf 和 printf,其中之一不支持浮点只是为了缩小代码大小。然而,按照他们的方式去做可能是有充分理由的。

避免拉入所有 stdio 的唯一方法是不使用其中任何一个 - 使用文件描述符函数(open 而不是 fopen,read 而不是 getc)。


0
投票

当您使用 printf() 时,您会添加大量代码,其目的是在 CLI 上打印一些字符。当编译器构建您的源代码时,它也会使用 printf() 源代码。这些来源充满了处理不同用例的东西。这是我们不想要的。

Dietlibcs 的目的是在您添加不必要的东西并缩小您的足迹时发出警告。老实说 - printf() 是非常没有必要的。

在你的情况下,我猜你想在 CLI 上打印一些东西。 您可以向内核发出信号来执行此操作。 write() 可以提供帮助,因为它对内核进行系统调用(我们记得 - Linux 中的一切都是文件。至少在 Windows 中它很安静)

一个小例子:

#include <unistd.h>
#include <fcntl.h>

int main(){
        int fd = open("/dev/tty", O_WRONLY);
        write(fd, "Hello World\n", sizeof("Hello World\n"));
        return 0;
}

我希望这有帮助。

为了更清楚地说明:

int fd = open("/dev/tty", O_WRONLY);

搜索描述,将信号发送到哪里。 在这种情况下,它是 1。 你可以写:

#include <unistd.h>

int main(){
        write(1, "Hello World\n", sizeof("Hello World\n"));
        return 0;
}

如果您使用的是 *nix,请进一步阅读:https://man7.org/linux/man-pages/man2/write.2.html

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