我正在尝试使用 memset
编写一些裸机代码样式循环在其中:
for (int i = 0; i < N; ++i) {
arr[i] = 0;
}
它是用 GCC 编译的,并且 GCC 足够聪明,可以将其转换为对 memset()
的调用。 .不幸的是,因为它是裸机,我没有 memset()
(通常在 libc 中)所以我收到链接错误。 undefined reference to `memset'
似乎进行此转换的优化是 -ftree-loop-distribute-patterns
:Perform loop distribution of patterns that can be code generated with calls to a library. This flag is enabled by default at -O2 and higher, and by
-fprofile-use
and-fauto-profile
.
所以one person's solution只是降低优化级别。不是很满意。
我还找到了 this really helpful page这解释了
-ffreestanding
不足以让 GCC 不这样做,而且基本上别无选择,只能提供您自己的 memcpy
实现。 , memmove
, memset
和 memcmp
.我很乐意这样做,但是怎么做?如果我只写
memset
编译器将检测其中的循环并将其转换为对 memset 的调用!事实上,在我使用的 CPU 供应商提供的代码中,我发现了这条评论:/*
// This is commented out because the assembly code that the compiler generates appears to be
// wrong. The code would recursively call the memset function and eventually overruns the
// stack space.
void * memset(void *dest, int ch, size_t count)
...
所以我认为这就是他们遇到的问题。我如何提供
memset
的 C 实现没有编译器将其优化为对自身的调用并且没有禁用该优化?
最佳答案
啊哈我签到了the glibc code还有一个 inhibit_loop_to_libcall
听起来应该这样做的修饰符。是defined like this :
/* Add the compiler optimization to inhibit loop transformation to library
calls. This is used to avoid recursive calls in memset and memmove
default implementations. */
#ifdef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
# define inhibit_loop_to_libcall \
__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
#else
# define inhibit_loop_to_libcall
#endif
关于c - 如何提供 memcpy 的实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67210527/