这种有效类型规则是否严格符合? [英] Is this use of the Effective Type rule strictly conforming?
问题描述
C99和C11中的有效类型规则规定,没有声明类型的存储可以用任何类型写入,并且存储非字符类型的值将相应地设置存储的有效类型。
抛开INT_MAX可能小于123456789的事实,以下代码对Effective Type规则的使用是否严格符合?
#include< stdlib.h>
#include< stdio.h>
/ *使用int执行一些计算,然后浮点数,
,然后是int。
如果两个结果都是需要的,do_test(intbuff,floatbuff,1);
仅适用于int,do_test(intbuff,intbuff,1);
仅用于float,do_test(floatbuff,float_buff,0);
后两种用法需要存储没有声明的类型。
* /
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\\\
,iresult,fresult);
}
返回0;
}
在我阅读标准版时,所描述的函数的所有三种用法评论应严格符合(整数范围问题除外)。代码应该输出 1234567890 1234000000.00
。然而,GCC 7.2输出 1234056789 1157904.00
。我认为当 leave_as_int
为0时,它在将123400000.0f存储到<$ c $之后将123400000存储到 * p1
c> * p2 ,但我在标准中没有看到任何可以授权此类行为的内容。我错过了什么,或者是gcc不符合?
The Effective Type rule in C99 and C11 provides that storage with no declared type may be written with any type and, that storing a value of a non-character type will set the Effective Type of the storage accordingly.
Setting aside the fact that INT_MAX might be less than 123456789, would the following code's use of the Effective Type rule be strictly conforming?
#include <stdlib.h>
#include <stdio.h>
/* 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;
}
From my reading of the Standard, all three usages of the function described in the comment should be strictly conforming (except for the integer-range issue). The code should thus output 1234567890 1234000000.00
. GCC 7.2, however, outputs 1234056789 1157904.00
. I think that when leave_as_int
is 0, it's storing 123400000 to *p1
after it stores 123400000.0f to *p2
, but I see nothing in the Standard that would authorize such behavior. Am I missing anything, or is gcc non-conforming?
Yes, this is a gcc bug. I've filed it (with a simplified testcase) as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82697 .
这篇关于这种有效类型规则是否严格符合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!