1 c unsigned gcc segmentation-fault
我已经提炼了一个问题,这让我弄清楚发生了什么,但仍然不是原因.
int main() {
unsigned int a = 2;
char c[2] = {};
char* p = &c[1];
return p[1 - a];
}
Run Code Online (Sandbox Code Playgroud)
重写最后一行时更清楚一点.
return *(p + (1 - a)); /* equivalent */
return *(p + 1 - a); /* works */
return *(p + (1 - (int)a)); /* works */
Run Code Online (Sandbox Code Playgroud)
我很惊讶编译器没有在内部删除括号.而且更多的是它显然试图保持类型的暂时负面结果unsigned int.除非这不是分段错误的原因.在汇编程序输出中,带括号和不带括号的代码之间的差别很小.
- movl $1, %eax
- subl -12(%rbp), %eax
- movl %eax, %edx
+ movl -12(%rbp), %eax
+ movl $1, %edx
+ subq %rax, %rdx
Run Code Online (Sandbox Code Playgroud)
问题是在表达式中1 - a,1被提升为unsigned int,所以你有1U - 2U下溢UINT_MAX.这里带回家的消息是,在同一表达式中混合有符号和无符号整数时,您必须非常小心.
如果您当然启用了警告,那么好的编译器可能不会警告您这种用法:
main.c: In function 'int main()':
main.c:5:19: warning: '*((void*)& c +4294967296)' is used uninitialized in this function [-Wuninitialized]
return p[1 - a];
Run Code Online (Sandbox Code Playgroud)