c - Why is the compiler confused into a SIGSEGV by unsigned int? -
I have solved a problem, which has given me a sense of what is going on, but still not at all.
int main () {unsigned int a = 2; Four c [2] = {}; Char * p = & amp; C [1]; Return P [1 - A]; } This is a bit clearer when the last line is rewritten.
return * (P + (1 - A)); / * Equivalent * / return * (P + 1 - A); / * Work * / return * (P + (1 - (int))); / * Functions * / I'm surprised that the compiler does not remove the bracket internally. And more so that it clearly tries to capture a temporary negative result of type unsigned int unless there is a reason for division fault. The output of the assembler has a slight difference between the brackets and without the code. - movl $ 1,% eax - subl-12 (% rbp),% eax - movl% eax,% edx + movl-12 (% rbp),% eax + movl $ 1 ,% edx + subq% rax,% rdx
Regarding this forcible rules The expression is 1-a as a unsigned int , and the result is in an underflow. The compiler can not remove the bracket because you are mixing the types, consider your cases: return * (P + (1 - A)); / * Equals * / first calculates 1-a , but treats it as a unsigned int . This is less than an unsigned type, and gives maximum value for unsigned int it is then added to the indicator, resulting in p + (1 <31) , if unsigned int is 32-bit, such as an indicator is removed for some, it is unlikely to be a valid memory location. return * (P + 1 - A); It calculates p + 1 and then decreases a , resulting in dereferencing p- 1 . This is technically undefined behavior, but perhaps (in most implementations) a reference to a valid memory spot on the stack. return * (p + (1 - (int) a)); / * Functions * / This adds a a to a signed int , and then 1-A < / Counts the code, which is -1 . You can again dereference p-1 .
Comments
Post a Comment