【发布时间】:2019-11-28 00:36:27
【问题描述】:
Clang 6.0.1 avxintrin.h 有声明:
static __inline __m256i __DEFAULT_FN_ATTRS _mm256_set1_epi32(int)
GCC 5.5 有:
extern __inline __m256i __attribute__((__gnu_inline__, _always_inline__, __artificial__)) _mm256_set1_epi32(int)
为什么会有一个extern 和一个static? 这在一个调用_mm256_set1_epi32 的inline 函数中为我显示。 Clang 希望它被声明为static:
#include <immintrin.h>
inline void SimdBlockBloomFilter_make_mask() {
_mm256_set1_epi32(1);
}
-Weverything:
warning: static function '_mm256_set1_epi32' is used in an inline
function with external linkage [-Wstatic-in-inline]
使用 Clang++ 编译时,不会显示此错误。
【问题讨论】:
-
可能写它们的人认为差异并不重要。内在函数的全部意义在于完全内联,链接是无关紧要的,除非作为后备,以防有人获取内在函数的地址。我不确定正确的解决方法是什么。
-
@PeterCordes 我想知道他们为什么还要写修饰符
static或extern。他们似乎可以不用。 -
static inline在使用-fPIC编译的代码中很有用。并非所有编译器都同意inline foo() { ... }取代具有非隐藏 ELF 可见性的符号的符号插入。因此该函数实际上可能无法内联。除此之外,是的inline foo() { ... }确实意味着不必发出独立定义(假设编译器选择在任何地方内联它),因此不需要static。我也很好奇static或extern在 C 或 C++ 中还有什么其他原因。 -
@PeterCordes 您的编译器将始终为
inline foo()发出普通函数代码和符号,因为该函数具有外部链接并且可以在翻译单元之外被引用。但是如果它永远不会被调用,你的链接器会删除该代码。 -
@user6556709:这仅适用于 C 中的
extern inline,而在 C++ 中则完全不适用。 godbolt.org/z/y2AoK7 显示 gcc/clang asm 输出,甚至在组装之前。常规的inline还承诺每个呼叫站点都可以看到相同的定义。当前编译器通过仅在当前翻译中存在编译器选择不内联的调用站点时才发出独立定义来优化该过程,从而节省编译和链接期间的工作。 (顺便说一句,我认为在写我之前的评论时我可能会得到一个独立的定义,但我检查了 Godbolt 所以把它省略了。)
标签: c gcc static clang intrinsics