gpt4 book ai didi

c - 这段代码是否违反了严格的别名规则?

转载 作者:太空狗 更新时间:2023-10-29 16:34:04 26 4
gpt4 key购买 nike

问题:

  • 下面的这段代码是否违反了严格的别名规则?也就是说,是否允许智能编译器打印 00000 (或其他一些令人讨厌的效果),因为首先作为其他类型访问的缓冲区然后通过 int* 访问?
  • 如果没有,将只移动 ptr2 的定义和初始化在大括号之前(所以 ptr2 已经被定义,当 ptr1 进入范围时)打破它?
  • 如果没有,删除大括号(所以 ptr1ptr2 在同一范围内)会破坏它吗?
  • 如果是,如何修复代码?

  • 额外问题:如果代码没问题,并且 2. 或 3. 也不要破坏它,如何更改它以破坏严格的别名规则(例如,将花括号循环转换为使用 int16_t )?
    int i;
    void *buf = calloc(5, sizeof(int)); // buf initialized to 0

    {
    char *ptr1 = buf;
    for(i = 0; i < 5*sizeof(int); ++i)
    ptr1[i] = i;
    }

    int *ptr2 = buf;
    for(i = 0; i < 5; ++i)
    printf("%d", ptr2[i]);

    寻找确认,如此简短(ish),关于此特定代码的专家答案,理想情况下使用最少的标准引号,这就是我所追求的。我没有对严格的别名规则进行长时间的解释,只解释与此代码有关的部分。如果答案能明确列举上面编号的问题,那就太好了。

    还假设一个没有整数陷阱值的通用 CPU,我们也说 int是 32 位和二进制补码。

    最佳答案

    不,它没有,但这只是因为内存已分配,并使用字符类型写入。

    内存是使用 malloc 分配的。该对象没有声明 1 类型,因为它是用 malloc 分配的。因此该对象没有任何有效类型。

    然后代码使用类型 char 访问和修改对象。 .由于类型为2 char并且没有复制具有有效类型的对象5,复制不会将有效类型设置为char对于本次和后续访问,但将有效类型设置为 char ,仅在访问期间3。访问后,对象不再具有有效类型。

    然后类型int用于访问和仅读取该对象。由于对象没有有效类型,它变成3 int ,在读取期间。访问后,对象不再具有有效类型。如 int明显兼容有效类型int ,行为被定义。

    (假设读取的值不是 int 的陷阱表示。)

    您是否使用与 int 不兼容的非字符类型访问和修改了对象? ,行为将是未定义的。

    假设您的示例是(假设 sizeof(float)==sizeof(int) ):

    int i;
    void *buf = calloc(5, sizeof(float)); // buf initialized to 0

    {
    float *ptr1 = buf;
    for(i = 0; i < 5*sizeof(float); ++i)
    ptr1[i] = (float)i;
    }

    int *ptr2 = buf;
    for(i = 0; i < 5; ++i)
    printf("%d", ptr2[i]);

    对象的有效类型,当 float s 正在被写入,变成 float 类型, 在写入期间以及对不修改它的对象的所有后续访问期间。当这些对象被 int 访问时有效类型保持 float ,因为这些值只是被读取而不是被修改。之前的写入使用 float将有效类型设置为 float永久直到下一次写入此对象(在这种情况下没有发生)。类型 intfloat不兼容4,因此行为未定义。

    (以下所有文字均引自:ISO:IEC 9899:201x)

    1(6.5 表达式 6)
    访问其存储值的对象的有效类型是该对象的声明类型(如果有)。 87) 分配的对象没有声明类型。

    2 (6.5 表达式 6)
    如果一个值通过一个类型不是字符类型的左值存储到一个没有声明类型的对象中,那么左值的类型将成为该访问的对象的有效类型,并且对于不修改储值。

    3 (6.5 表达式 6)
    对于没有声明类型的对象的所有其他访问,对象的有效类型只是用于访问的左值的类型。

    4 (6.5 表达式 8)
    对象的存储值只能由具有以下之一的左值表达式访问
    以下类型:88)
    — 与对象的有效类型兼容的类型,
    — 与对象的有效类型兼容的类型的限定版本,
    — 对应于有效类型的有符号或无符号类型
    目的,
    — 一种类型,它是与限定版本对应的有符号或无符号类型
    对象的有效类型,
    — 一个聚合或 union 类型,其中包括上述类型之一
    成员(包括递归地,子聚合或包含 union 的成员),或
    — 一种字符类型。

    5 (6.5 表达式 6)
    如果使用 memcpy 或 memmove 将值复制到没有声明类型的对象中,或者复制为字符类型的数组,则该访问和不修改该值的后续访问的修改对象的有效类型是从中复制值的对象的有效类型(如果有)。

    关于c - 这段代码是否违反了严格的别名规则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38347994/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com