V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iqoo
V2EX  ›  程序员

[C] Linux 中 htonl(常量) 不能在编译期计算出来吗?

  •  
  •   iqoo · 2023-02-08 16:31:12 +08:00 · 829 次点击
    这是一个创建于 647 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Mac 中编译通过的代码在 Linux 中编译不通,问题在于 enum 中使用了 htonl

    enum A {
      X = htonl(1),
    };
    
    

    报错:

    ./****: error: expression is not an integral constant expression
      X = htonl(1),
          ^~~~~~~~
    /usr/include/netinet/in.h:404:21: note: expanded from macro 'htonl'
    #   define htonl(x)     __bswap_32 (x)
                            ^~~~~~~~~~~~~~
    ./****: note: non-constexpr function '__bswap_32' cannot be used in a constant expression
    

    而 Mac 中 htonl 是这样的:

    #define htonl(x)        __DARWIN_OSSwapInt32(x)
    
    #define __DARWIN_OSSwapInt32(x) \
        (__builtin_constant_p(x) ? __DARWIN_OSSwapConstInt32(x) : _OSSwapInt32(x))
    

    如果是常量,直接用 __DARWIN_OSSwapConstInt32 宏算出结果,不是常量则在运行时 bswap 计算。所以 htonl(常量) 能在 enum 中使用。

    为什么 Linux 没有实现这个特性?

    Linux: 5.4.0-126-generic   (clang version 10.0.0-4ubuntu1)
    MacOS: 22.1.0 Darwin       (Apple clang version 14.0.0)
    
    5 条回复    2023-02-09 11:55:16 +08:00
    tool2d
        1
    tool2d  
       2023-02-08 16:41:11 +08:00
    我试了一下,这样写可以:

    enum A {
    X = __builtin_bswap32(1),
    };

    估计还是为了什么兼容性吧。
    minami
        2
    minami  
       2023-02-08 16:53:00 +08:00
    那你用__constant_htonl 呗
    ysc3839
        3
    ysc3839  
       2023-02-08 21:59:38 +08:00 via Android
    C++的话自己实现个 constexpr 的即可,C 不行。
    ysc3839
        4
    ysc3839  
       2023-02-08 22:08:31 +08:00 via Android   ❤️ 1
    __DARWIN_OSSwapConstInt32 这个应该是编译器的 intrinsic 。按照 BSD socket 的标准,htonl 应该是个函数来的,Linux 实现成了一个函数,所以不支持。
    你要编译期且跨平台的话,用 C++的 std::endian 加上 if constexpr 是最简单的。
    C 的话可以用编译器提供的字节序宏以及翻转字节序的 intrinsic 。
    iqoo
        5
    iqoo  
    OP
       2023-02-09 11:55:16 +08:00
    @ysc3839 我用 gcc/clang 的 __builtin_constant_p 实现了,可以在编译期判断是不是常量。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2962 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 08:51 · PVG 16:51 · LAX 00:51 · JFK 03:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.