gpt4 book ai didi

c - 在动态 bool 数组上使用 memset 是否定义明确?

转载 作者:太空狗 更新时间:2023-10-29 16:55:44 25 4
gpt4 key购买 nike

就严格别名而言,这段代码的行为是否定义明确?

_Bool* array = malloc(n);
memset(array, 0xFF, n);
_Bool x = array[0];

有效类型规则对 memcpymemmove (C17 6.5 §6) 有特殊情况,但对 memset 没有。

我认为有效类型变为 unsigned char。因为 memset 的第二个参数需要转换为 unsigned char (C17 7.24.6.1) 并且由于有效类型的规则,(C17 6.5 §6):

...or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one.

  • 问题一:memset调用后,array中存储的数据的有效类型是什么?
  • 问题 2:array[0] 访问是否因此违反了严格的别名?因为 _Bool 不是从严格的别名规则中排除的类型(与字符类型不同)。

最佳答案

  1. memset 不会改变有效类型。 C11 (C17) 6.5p6:

    1. The effective type of an object for an access to its stored value is the declared type of the object, if any. [ This clearly is not the case. An allocated object has no declared type. ]

      If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. [ this is not the case as an lvalue of character type is used by memset! ]

      If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. [ this too is not the case here - it is not copied with memcpy, memmove or an array of characters ]

      For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access. [ therefore, this has to apply in our case. Notice that this applies to accessing it as characters inside memset as well as dereferencing array. ]

    因为值是用 一个 lvalue 存储的,该 lvaluememset 中具有字符类型,而不是 从另一个复制字节具有字符类型左值的对象(该子句将 memcpymemmove 等同于用显式 for 循环执行相同操作! ), 它没有得到一个有效类型,元素的有效类型是 _Bool 对于那些通过 array 访问的。

    C17 标准中可能有未指定的部分,但这肯定不是其中之一。

  2. array[0] 不会违反有效类型规则。

    这不会使使用 array[0] 的值变得合法。它可以(而且很可能)是一个陷阱值!

    我尝试了以下功能

    #include <stdio.h>
    #include <stdbool.h>

    void f1(bool x, bool y) {
    if (!x && !y) {
    puts("both false");
    }
    }


    void f2(bool x, bool y) {
    if (x && y) {
    puts("both true");
    }
    }

    void f3(bool x) {
    if (x) {
    puts("true");
    }
    }

    void f4(bool x) {
    if (!x) {
    puts("false");
    }
    }

    array[0] 作为任何参数 - 为了避免编译时优化,这是单独编译的。当使用 -O3 编译时,会打印以下消息:

    both true
    true

    在没有任何优化的情况下

    both false
    both true
    true
    false

关于c - 在动态 bool 数组上使用 memset 是否定义明确?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53171804/

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