将int当作char解析是否属于UB?小端架构下是否必然可行?
这段错误C代码的运行有效性分析
首先看学生写的问题代码,意图是将字符串s的第i位字符转换为对应数值,但写法存在严重问题:
int temp2 = s[i]; int temp = strtol(&temp2, NULL, 10);
小端架构下是否能始终正常运行?
答案是不能,哪怕是小端架构,这段代码也无法保证始终正常工作,因为它本质上属于C标准明确禁止的未定义行为(UB),而非单纯的字节序问题。
除大端CPU外,还有哪些导致代码失效的情况?
即使是小端系统,以下情况都会让代码失效:
int的高字节包含垃圾值:strtol要求传入指向以空字符结尾的C字符串的指针,但这里传入的是int类型变量temp2的地址。小端架构下temp2的低字节是s[i]的ASCII值,但高字节是栈上的随机垃圾数据。只有当所有高字节恰好都是0时,strtol才会误把这个内存区域当成合法的单字符字符串;只要高字节有非0值,strtol就会读到一堆乱码字符,解析结果完全不可控。- 违反严格别名规则:C标准不允许通过
char*类型指针访问int类型变量(除非是指向char的指针),这种类型双关会触发编译器的激进优化。比如编译器可能认为&temp2指向的是int,不会被当作字符串访问,进而优化掉temp2的赋值操作,导致strtol读取完全随机的内存内容。 int的字节长度问题:如果系统中int是2字节(部分嵌入式系统),即使是小端,高字节的垃圾值依然会让strtol读到非空结尾的非法序列,解析失败。- 有符号
char的符号扩展:如果系统中char是有符号类型,当s[i]是大于127的扩展ASCII字符时,赋值给int会触发符号扩展,导致temp2的高字节全为1。此时strtol读到的是包含0xff等非可打印字符的序列,会直接返回0或错误值。
总结来说,这段代码的问题核心是完全违背了C语言的内存访问规则和strtol的使用要求,属于明确的未定义行为,无论什么架构都不能依赖它正常运行,小端架构下的"正常工作"只是极其偶然的巧合。
内容的提问来源于stack exchange,提问作者Costantino Grana
相关产品推荐
相关产品推荐

