c - 这种对有效类型规则的使用是否严格遵守?

标签 c gcc undefined-behavior c99 strict-aliasing

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

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

#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;
}

根据我对标准的阅读,注释中描述的函数的所有三种用法都应该严格符合(整数范围问题除外)。因此,代码应输出 1234567890 1234000000.00。然而,GCC 7.2 输出 1234056789 1157904.00。我认为当 leave_as_int 为 0 时,它在将 123400000.0f 存储到 *p2 后,将 123400000 存储到 *p1 ,但我在授权此类行为的标准。我是否遗漏了什么,或者 gcc 不符合要求?

最佳答案

是的,这是一个 gcc 错误。我已将其(带有简化的测试用例)归档为 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82697 .

关于c - 这种对有效类型规则的使用是否严格遵守?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46592132/

相关文章:

c - 扩展大型 C 编程项目 - 对各种函数的 undefined reference

c - 如何在 C 中不打印整数值

c - 将 yuv 图像覆盖在另一图像上

c++ - 如何修改按值传递的原始变量的内容?

c - Scanf 跳过 C 中的每个其他 while 循环

为 Vala 编译 gcrypt

gcc - OpenMP - 线程如何决定何时推迟任务以及何时立即执行

c++ - 对已删除的数组进行指针运算仍然合法吗?

c++ - 堆分配的 const 对象与非 const 对象有何不同?

c++ - 为什么有些东西在 C++ 中留下未定义的行为?如果其中一些在标准中预先定义不是更好吗?