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

现代化 C 使用体验

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

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

    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 。
    unifier
        33
    unifier  
       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 就行了。
    zackwu
        36
    zackwu  
       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     Solana     4653 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 40ms UTC 01:09 PVG 09:09 LAX 17:09 JFK 20:09
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86