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

C语言不同翻译单元同名struct不同定义是否属于未定义行为

现有代码示例

0.c

#include <stdio.h>

struct test{
 int a;
};

struct test get(int in);

int main(){
 struct test t = get(1234);
 printf("%d\n",t.a);

 return 0;
}

1.c

struct test{
 char a;    // 此处成员为char而非int
};

struct test get(int in){
  struct test t = {in};
  return t;
}

问题解答

这段代码属于明确的未定义行为。
很多人对C语言的规则存在片面误解:C语言确实没有C++那样成文的单一定义规则(ODR),也允许不同翻译单元定义同名结构体,但前提是这些同名结构体没有和跨单元调用的外部资源绑定:

  • 如果两个翻译单元的同名struct test仅在各自单元内部使用,没有关联任何跨单元调用的外部函数、外部变量,那这种用法完全合法:两个结构体只是名字碰巧相同,本质是完全独立的两个类型,互不干扰。
  • 但本示例的核心问题在于,跨翻译单元的外部函数get的声明和实现类型不兼容:
    1. 0.c中声明的get函数返回值是包含int成员的struct test,常规大小为4字节
    2. 1.c中实现的get函数返回值是包含char成员的struct test,常规大小为1字节
      C标准明确要求,所有对具有外部链接的同一个函数的声明,必须指向兼容类型,否则就属于未定义行为。这里两个get函数的返回类型是完全不兼容的结构体,完全符合未定义行为的判定条件。

实际运行时可能出现多种不可预期的结果:比如打印1234的低8位数值、打印随机乱数、程序直接崩溃等,都是未定义行为的典型表现。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 21:06:03