这种有效类型规则的使用是否严格符合?

C99和C11中的有效类型规则规定,可以使用任何类型写入没有声明类型的存储,并且存储非字符类型的值将相应地设置存储的有效类型。

撇开INT_MAX可能小于123456789的事实,以下代码对有效类型规则的使用是否严格符合?

#include  #include  /* Performs some calculations using using int, then float, then int. If both results are desired, do_test(intbuff, floatbuff, 1); For int only, do_test(intbuff, intbuff, 1); For float only, do_test(floatbuff, float_buff, 0); The latter two usages require storage with no declared type. */ void do_test(void *p1, void *p2, int leave_as_int) { *(int*)p1 = 1234000000; float f = *(int*)p1; *(float*)p2 = f*2-1234000000.0f; if (leave_as_int) { int i = *(float*)p2; *(int*)p1 = i+567890; } } void (*volatile test)(void *p1, void *p2, int leave_as_int) = do_test; int main(void) { int iresult; float fresult; void *p = malloc(sizeof(int) + sizeof(float)); if (p) { test(p,p,1); iresult = *(int*)p; test(p,p,0); fresult = *(float*)p; free(p); printf("%10d %15.2f\n", iresult,fresult); } return 0; } 

从我对标准的阅读中,评论中描述的函数的所有三种用法都应该严格符合(整数范围问题除外)。 因此代码应输出1234567890 1234000000.00 。 但是,GCC 7.2输出1234056789 1157904.00 。 我认为当leave_as_int为0时,在将123400000.0f存储到*p2之后,它将123400000存储到*p1 ,但我在标准中没有看到任何会授权此类行为的内容。 我错过了什么,还是gcc不合格?

是的,这是一个gcc bug。 我已将其(使用简化的测试用例)提交为https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82697 。

生成的机器代码无条件地写入两个指针:

 do_test: cmpl $1, %edx movl $0x4e931ab1, (%rsi) sbbl %eax, %eax andl $-567890, %eax addl $1234567890, %eax movl %eax, (%rdi) ret 

这是一个GCC错误,因为所有商店都应该改变所访问内存的动态类型 。 我不认为这种行为是标准规定的; 这是GCC的延伸。

你能提交一个GCC错误吗?