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

现代化 C 使用体验

  •  8
     
  •   lcj2class · 2022-05-01 16:35:35 +08:00 · 7801 次点击
    这是一个创建于 697 天前的主题,其中的信息可能已经有所发展或是发生改变。

    自己一些粗浅的使用体验,欢迎大家批评指正。

    48 条回复    2022-05-06 08:05:21 +08:00
    d16uga1l
        1
    d16uga1l  
       2022-05-01 16:42:17 +08:00
    真棒
    cmdOptionKana
        2
    cmdOptionKana  
       2022-05-01 16:51:28 +08:00
    干货满满呀
    icyalala
        3
    icyalala  
       2022-05-01 16:59:41 +08:00   ❤️ 4
    用 GNU extension 特性要慎重,这会让你代码可移植性变差。。
    echo1937
        4
    echo1937  
       2022-05-01 17:21:51 +08:00 via iPhone
    @icyalala 同意,我在 Mac 上直接 clang ,extension 就❌了
    dongcidaci
        5
    dongcidaci  
       2022-05-01 18:21:39 +08:00
    Linux 内核也开始支持 c11 了,想想有点小激动
    dongcidaci
        6
    dongcidaci  
       2022-05-01 18:30:42 +08:00 via Android
    错误处理那一节感觉没太看懂,前后处理方式有什么区别呢,就是把错误码封装到了结构体里面吗
    xiri
        7
    xiri  
       2022-05-01 18:41:46 +08:00 via Android
    @dongcidaci 前一个做法是 return 错误码,函数处理结果通过入参的指针带出,这样链式调用的话后一个函数只能拿到前一个函数返回的错误码,而没法用它的处理结果作为自己的输入;后一种做法将错误码和处理结果封装在一起 return ,可以避免这种问题
    xiri
        8
    xiri  
       2022-05-01 18:46:15 +08:00 via Android
    @icyalala 但是 container_of (其中用到的 typeof 关键字是 GNU C 扩展的)是真的香,将我从各种重复的链表操作中解放了出来😂
    Frytea
        9
    Frytea  
       2022-05-01 19:14:52 +08:00
    @dongcidaci 准确说应该是 Linux 5.18 开始采用 C11 标准,我理解是使用新标准来编译和实现,对标准的支持应该是编译器的工作呀
    12101111
        10
    12101111  
       2022-05-01 19:28:34 +08:00
    cleanup 扩展 clang 没有,intel 的 iwd 用了这玩意,我移植了几次之后懒得管了,直接删了用回 wpa_supplicant

    (只安装了 clang 的 Gentoo 系统)
    codefever
        11
    codefever  
       2022-05-01 20:31:56 +08:00
    下次如果能直接复制到帖子里就更好了
    secondwtq
        12
    secondwtq  
       2022-05-01 20:49:19 +08:00
    虽然拿一堆 extension 来说“Modern C”有些呃呃,不过 Clang 好像老早就支持了 cleanup 啊 ...
    secondwtq
        13
    secondwtq  
       2022-05-01 20:50:43 +08:00
    另外 Clang 一直在试图和 GCC 保持兼容,社区里面好像有不止一股力量想要用这玩意编译 Kernel ( which 强依赖各种 GCC 扩展
    wheeler
        14
    wheeler  
       2022-05-01 21:26:50 +08:00 via iPhone
    Buges
        15
    Buges  
       2022-05-01 22:06:13 +08:00 via Android
    C 演进的实在太慢了,zig 才能叫 modern C ,它们之间的 interoperability 近似于 Java 和 kotlin ,是真正有希望取代 C 的。
    lcj2class
        16
    lcj2class  
    OP
       2022-05-01 22:42:23 +08:00
    @12101111 #10 是不是版本比较低,clang 是支持 cleanup 的,我 macOS 上的的 clang 一直用的很好
    12101111
        17
    12101111  
       2022-05-01 22:55:54 +08:00   ❤️ 1
    @secondwtq
    @lcj2class

    抱歉,记错了,iwd 是 cleanup 和 gcc 的另一个扩展一起用了 https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html

    这个 gcc 扩展 clang 不支持,不过据说也有可能进 c23
    lcj2class
        18
    lcj2class  
    OP
       2022-05-01 23:00:23 +08:00
    @Buges #15 慢不是坏事,慢工出细活。C++ 倒是演进得快, 但发展到现在已经太臃肿了。
    LotusChuan
        19
    LotusChuan  
       2022-05-02 00:42:55 +08:00   ❤️ 3
    指针那块有个很简单的区分数组指针和指针数组的方式,就是看优先级:[ ]的优先级比*高,所以 int *arr[100]是指针数组; int (*ptr)[100]是数组指针。感觉你写得有点复杂了。
    ecnelises
        20
    ecnelises  
       2022-05-02 00:50:46 +08:00   ❤️ 1
    GCC 的主要扩展 Clang 都支持,其余的 Clang 处在一个随缘状态:不保证一定支持,但你要实现也没什么人反对。

    滥用编译器扩展的确会影响可移植性,但两害相权取其轻,GCC 扩展的可移植性比起内联汇编和各种指令集 /操作系统强相关的自带函数还是好多了。Mac 迁移到 ARM 算是在这方面敲醒了一些人。只要把这些特定编译器的扩展封到宏 /函数里,然后对不支持的编译器加上#error ,问题不大。
    hronro
        21
    hronro  
       2022-05-02 01:16:04 +08:00
    我还是更看好 Zig
    documentzhangx66
        22
    documentzhangx66  
       2022-05-02 02:10:57 +08:00
    这玩意你还能写那么多,我觉得一点都不现代。

    真要现代,应该能直接把易语言、Python 之类的源码,现场编译成高优化的可执行文件,然后执行,并且跨平台,还支持浏览器。
    zengmingyang96
        23
    zengmingyang96  
       2022-05-02 02:14:23 +08:00
    写的很好,赞
    Trim21
        24
    Trim21  
       2022-05-02 03:02:56 +08:00
    "在 Go 中,会选择同一大版本下,最大的小版本"

    go 选择的是最小的小版本,你看你这图里选择的是 B1.2 不是 B1.3
    XhstormR02
        25
    XhstormR02  
       2022-05-02 08:00:41 +08:00 via Android
    有介绍 zig 的吗,有啥优点
    XhstormR02
        26
    XhstormR02  
       2022-05-02 08:02:00 +08:00 via Android
    @hronro
    @Buges
    zig 跟 rust 比有什么有什么优点吗
    lcj2class
        27
    lcj2class  
    OP
       2022-05-02 09:53:51 +08:00
    @Trim21 #24 B 没有冲突,有冲突的是 C ,Go 选择的是 C1.4 ,而不是 C1.3
    Trim21
        28
    Trim21  
       2022-05-02 09:59:20 +08:00
    @lcj2class #27 假如有个 C1.5 呢,go 会选 C1.4 还是 C1.5 ?应该是 C1.4 吧

    选“会选择同一大版本下,最大的小版本”就是 C1.5 ,“会选择同一大版本下,最小的小版本”就是 C1.4
    Trim21
        29
    Trim21  
       2022-05-02 10:00:29 +08:00
    @lcj2class #27 而且 C 依赖也没有冲突 - -
    Trim21
        30
    Trim21  
       2022-05-02 10:05:29 +08:00
    @Trim21 #28 哦我明白你的意思了,你这句话的范围是 gomod 里面写的版本号,不是 pkg 发布的版本号
    cmdOptionKana
        31
    cmdOptionKana  
       2022-05-02 10:13:14 +08:00
    @documentzhangx66 你说的是未来,不是现代。

    已经实现的,才叫现代;你说的目前还没有实现,未来才能实现。
    52coder
        32
    52coder  
       2022-05-02 10:40:53 +08:00
    我司禁止使用 gcc 扩展,只能写一些 clean c code 。
    zacharyjia
        33
    zacharyjia  
       2022-05-02 10:42:29 +08:00
    @Buges
    @hronro
    zig 的开发进度实在是太慢了,之前看开发团队说预计 1.0 要到 2025 年🤨直接就丧失兴趣了
    Nasei
        34
    Nasei  
       2022-05-02 12:18:36 +08:00
    不太喜欢用编译器扩展
    waruqi
        35
    waruqi  
       2022-05-02 12:33:40 +08:00
    包管理直接用 xmake 就行了。
    keith1126
        36
    keith1126  
       2022-05-02 13:04:50 +08:00
    很棒的文章,学到了很多之前不了解的东西
    Buges
        37
    Buges  
       2022-05-02 14:50:38 +08:00 via Android
    @XhstormR02 定位不一样,rust 是 modern C++,追求安全、抽象,zig 是 modern C ,追求简单、直接。
    详细了解直接去官网看 https://ziglang.org/
    hronro
        38
    hronro  
       2022-05-02 16:49:35 +08:00
    gowk
        39
    gowk  
       2022-05-02 17:38:22 +08:00
    感谢 OP 的 SICP 库
    fantastM
        40
    fantastM  
       2022-05-03 01:43:42 +08:00
    楼主也是这篇文章的作者吧 https://mp.weixin.qq.com/s/zrxDgBjutbdvROQRYa3zrQ
    cnbatch
        41
    cnbatch  
       2022-05-03 04:53:43 +08:00
    @xiri 其实 container_of 不使用 typeof 也可以实现,FreeBSD 的源码就有:
    https://github.com/freebsd/freebsd-src/blob/main/sys/dev/cxgb/cxgb_adapter.h

    代码是:
    #define container_of(p, stype, field) ((stype *)(((uint8_t *)(p)) - offsetof(stype, field)))



    有意思的是,Linux 源码当中也有不用 typeof 来 define 的,而且似乎是唯一一处:
    https://github.com/torvalds/linux/blob/master/tools/lib/bpf/bpf_helpers.h

    #define container_of(ptr, type, member) \
    ({ \
    void *__mptr = (void *)(ptr); \
    ((type *)(__mptr - offsetof(type, member))); \
    })
    #endif

    稍微追溯了下提交历史,这是两年前新增的:
    https://github.com/torvalds/linux/blob/5fbc220862fc7a53a0455ccd2d96c82141e222d4/tools/lib/bpf/bpf_helpers.h

    仔细一看,原来是 BPF ,也是跟 BSD 有关的东西,或许这种写法属于“BSD-style”吧。但是跟 BSD 版本相比,bpf_helpers.h 的写法仍然更加接近于 Linux 的 typeof 版本。
    Bbird
        42
    Bbird  
       2022-05-03 08:57:51 +08:00
    @cnbatch #41 linux 内核源码的 container_of 没有使用 typeof 吧,全部都是三个参数的

    /**
    * container_of - cast a member of a structure out to the containing structure
    * @ptr: the pointer to the member.
    * @type: the type of the container struct this is embedded in.
    * @member: the name of the member within the struct.
    *
    */
    #define container_of(ptr, type, member) ({ \
    void *__mptr = (void *)(ptr); \
    ((type *)(__mptr - offsetof(type, member))); })
    Bbird
        43
    Bbird  
       2022-05-03 09:01:15 +08:00
    @cnbatch #41 较早的内核代码用了 typeof , 新的去掉了
    cnbatch
        44
    cnbatch  
       2022-05-03 13:54:10 +08:00
    @Bbird 重新下载了新的内核代码树看了下,确实是这样。很久以前看的时候他还是 typeof ,搞得我以为现在还是。原来现在甚至还有专门的 container_of.h ,方便了不少
    cnbatch
        45
    cnbatch  
       2022-05-03 14:01:53 +08:00
    @Bbird 现在的 container_of 去掉了 typeof ,但我想不到风格还是跟原来的差不多,依旧是先来一个变量赋值,下一行再做减法,并且仍然需要大括号。
    虽然终于不再依赖 typeof ,但相比之下,我仍然更喜欢 BSD 的那种。同样的效果,却更加简洁、易懂。
    按道理,GPL 代码照抄 BSD 是完全可以的。
    iClass
        46
    iClass  
       2022-05-03 17:56:31 +08:00 via Android
    和 C 一起出生的人 我叫 IC
    rahuahua
        47
    rahuahua  
       2022-05-03 18:14:21 +08:00
    @Buges zig 也不少年头了,影响力太小了
    lijiangang886
        48
    lijiangang886  
       2022-05-06 08:05:21 +08:00
    取代 C 这种伟大的事业,一听就是没可能做到的样子
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5730 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 01:50 · PVG 09:50 · LAX 18:50 · JFK 21:50
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.