You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RISC-V中局部初始化数组编译报memcpy未定义错误原因咨询

全局数组与局部初始化数组的编译差异原因分析

问题背景

我编写了一段C程序,初始版本中数组A、B为全局初始化数组,C为全局未初始化数组:

int A[size][size] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int B[size][size] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
int C[size][size];

int multiplication()
{
    //using array A, B and C here

    return 0;
}

使用以下命令编译:

riscv64-unknown-elf-gcc -ffreestanding -march=rv32im -mabi=ilp32 -nostartfiles  -nodefaultlibs -mno-relax crt0.s Myprogram.c -o Myprogram

编译过程正常,通过riscv64-unknown-elf-objdump -t Myprogram查看,数组A、B位于.data段,C位于.bss段。

但当我将数组A、B改为multiplication函数内的局部初始化数组后:

int C[size][size];

int multiplication()
{
int A[size][size] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int B[size][size] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
    //using array A, B and C here

    return 0;
}

编译出现错误:undefined reference to 'memcpy'。为什么全局数组不会触发这个问题,局部初始化数组却会调用memcpy?

原因分析

  • 全局初始化数组的处理逻辑:全局变量的内存空间在编译阶段就被分配到对应段——已初始化的进入.data段,未初始化的进入.bss段。对于A、B这类已初始化的全局数组,编译器会直接把初始化数据写入可执行文件的.data段,程序加载时操作系统会将这部分数据直接映射到内存中,不需要在运行时执行额外的复制操作,因此不会调用memcpy。

  • 局部初始化数组的处理逻辑:局部变量是在函数调用时才在栈上分配内存的。对于带有初始化值的局部数组,编译器会先把初始化数据存储在程序的只读数据段(.rodata)中,等函数执行时,通过memcpy将.rodata里的初始化数据批量复制到栈上的数组空间——这是编译器优化批量初始化操作的常规手段。而你编译时使用了-nodefaultlibs参数,没有链接标准库,memcpy作为标准库函数无法被找到,因此出现未定义引用的错误。

内容的提问来源于stack exchange,提问作者Sooora

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:55:19