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

刚发现 C 语言命名初始化语法糖(Designated Initializers)依赖标准库的 memset 和 memcpy

  •  1
     
  •   yuanix · 300 天前 · 1422 次点击
    这是一个创建于 300 天前的主题,其中的信息可能已经有所发展或是发生改变。
    struct proc test_proc_1 = {
          .name = "test_proc_1",
          .pid = 1,
          .hartid = 0,
          .state = PROC_READY,
          .cpu = {
              .pc = (u64)&test_proc_1,
          }};
    

    这段代码在链接的时候提示:

    undefined reference to `memset'
    undefined reference to `memcpy'
    

    让 ChatGPT 给我实现了一下,编译链接进去就好了。

    #include "kstring.h"
    
    void *memset(void *s, int c, size_t n)
    {
      unsigned char *p = s;
      while (n--)
        *p++ = (unsigned char)c;
      return s;
    }
    
    void *memcpy(void *dest, const void *src, size_t n)
    {
      unsigned char *d = dest;
      const unsigned char *s = src;
      while (n--)
        *d++ = *s++;
      return dest;
    }
    
    第 1 条附言  ·  300 天前
    用的 RISC-V gcc 编译器,因为是写个玩具 kernel ,所以不链接标准库
    10 条回复    2023-07-03 17:50:08 +08:00
    nightwitch
        1
    nightwitch  
       300 天前 via Android
    特定编译器的表现吧
    zhng920823
        2
    zhng920823  
       300 天前
    你这是写单片机程序还是别的不依赖操作系统的程序?
    按说即便以来依赖这个也是默认连接上了啊。
    zhng920823
        3
    zhng920823  
       300 天前
    写了个类似的程序, 但是分析程序连接的库函数后, 没有发现依赖 memset memcpy
    也可能优化掉了,虽然用了 -O0
    yuanix
        4
    yuanix  
    OP
       300 天前 via Android
    @zhng920823 不依赖操作系统的,写个玩具 kernel
    LaTero
        5
    LaTero  
       300 天前 via Android
    会不会是你的初始化顺序和字段的定义顺序不一样?不一样的时候 gcc 会报警告 iso c++不支持,可能是 gnu 拓展会到用 memset 和 memcpy 。我没有 freestanding 开发经验,瞎猜的。
    zhng920823
        6
    zhng920823  
       300 天前
    @yuanix #3 仰望大佬 是给 X86 机器写的还是给那些嵌入式设备写的? 有没有 github 地址
    yuanix
        7
    yuanix  
    OP
       300 天前   ❤️ 1
    @zhng920823 小菜鸡一个,摸鱼了解一点新东西,为 QEMU 模拟器的虚拟 RISC-V 设备写,刚开始写: https://github.com/peiyuanix/yuanix-riscv-os ,欢迎一起交流学习呀
    zagfai
        8
    zagfai  
       300 天前
    确实是会影响性能~
    agagega
        9
    agagega  
       299 天前
    没有装到 RISCV 的 cross GCC ,试了下 clang 和其他平台的 GCC ,没发现有这个行为。可以试试加上 -fno-builtin 和 -ffreestanding
    yuanix
        10
    yuanix  
    OP
       299 天前
    @agagega 试了一下加上还是要,明确指出初始化那行代码需要依赖 `memset`。

    我用的是 Debian ,riscv64-gcc 包名是 `gcc-riscv64-linux-gnu`
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   900 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:20 · PVG 06:20 · LAX 15:20 · JFK 18:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.