【问题标题】:Can an intrinsic compiler function be weakly defined or does Clang not respect weak attributes?可以弱定义内在编译器函数还是 Clang 不尊重弱属性?
【发布时间】:2021-07-10 09:32:17
【问题描述】:

假设有一个函数 _foo:

  • 是我使用的 Clang 版本所固有的,并且
  • 在 GCC 版本中没有定义。

我想为 Clang 和 GCC 以及各种版本编译我的代码。

我希望:

__attribute__((weak)) _foo (...) { my_foo(...); }

允许我在使用 Clang 编译时使用 Clang 版本,但如果使用没有将其作为内在函数的编译器(例如我当前的 GCC 版本),则使用 my_foo。

问题是 Clang 认为我在重新定义 _foo。

我可以 ifdef off of __ clang __ 但我担心的是,对于确实将 _foo 作为内在函数的 GCC 版本,编译会由于相同的重新定义错误而中断。

所以问题是:

  • weak 属性不能与内在函数一起使用吗?或
  • Clang 不尊重弱属性?

提前致谢。

【问题讨论】:

  • is that for GCC versions that do have _foo as an intrinsic, compilation will break due to the same redefinition error 这很正常,叫做“移植”,是的,那你就做#if defined(__clang__) || __GNUC__ < some_versionull

标签: c++ c gcc clang


【解决方案1】:

weak 属性不能与内在函数一起使用吗?

是的,函数没有链接,它是内在的。

Clang 不尊重弱属性?

Clang 理解弱属性。

我可以 ifdef off of __ clang __ 但我担心的是,对于确实将 _foo 作为内在函数的 GCC 版本,编译会由于相同的重新定义错误而中断。

那么你将 #if 特定的 gcc 版本。 This is how it works。一些“内在功能”不是标准的,所以不要指望一个标准的最终方式来处理它。如果您使用编译器特定功能,您将分别处理每个编译器,因为它编译器特定的。

但这种方法总体上是错误的。与其在保留的命名空间中提供编译器特定的函数,不如提供您自己的包装器,如果可能的话,可以选择使用编译器特定的函数:

 void foo(int arg) {
    #if defined(__clang__) && __clang_major__ > 4 // handle specific compiler versions
    // #if CONFIG_HAS_BUILTIN_FOO      // or use build system
        __builtin_foo(arg);
    #else 
        standard_compliant_algortihm();
    #endif
 }
 // use foo(arg) in your code

见前。 byteswap.h 从我的头顶。在 __*_<UPPER CASE LETTER>* 的保留命名空间中提供符号是未定义的行为。不要做。它是专门为编译器保留的命名空间,特别是为了让用户不要使用它们。不要在该命名空间中提供符号。

为了便于移植,您可以使用cmake (CheckSymbolExists(__builtin_foo)) 或autotools 或其他构建系统来检测编译器是否支持特定的内置函数,并可选择在您的代码中使用它如果编译器支持的话。

【讨论】:

    猜你喜欢
    • 2015-12-29
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多