相关疑难解决方法(0)

使用字符类型上次写入时,使用非字符类型读取对象时的未定义行为

假设unsigned int没有陷阱表示,请执行下面标记为(A)和(B)的语句中的任何一个或两个引发未定义的行为,为什么或为什么不这样做,以及(特别是如果您认为其中一个定义明确但另一个不定义),您认为标准中存在缺陷吗?我主要对当前版本的C标准(即C2011)感兴趣,但如果在标准的旧版本或C++中有所不同,我也想知道这一点.

(_Alignas在这个程序中用于消除因对齐不充分而导致的任何UB问题.我在解释中讨论的规则虽然没有说明对齐.)

#include <stdlib.h>
#include <string.h>

int main(void)
{
    unsigned int v1, v2;
    unsigned char _Alignas(unsigned int) b1[sizeof(unsigned int)];
    unsigned char *b2 = malloc(sizeof(unsigned int));

    if (!b2) return 1;

    memset(b1, 0x55, sizeof(unsigned int));
    memset(b2, 0x55, sizeof(unsigned int));

    v1 = *(unsigned int *)b1; /* (A) */
    v2 = *(unsigned int *)b2; /* (B) */

    return !(v1 == v2);
}
Run Code Online (Sandbox Code Playgroud)

我对C2011的解释是(A)引发未定义的行为,但(B)定义明确(存储未指定的值v2),因为:

  • memset被定义(§7.24.6.1)写入它的第一个参数作为-如果通过与字符类型,它被允许用于两左值b1b2每特殊情况下,在§6.5p7的底部.

  • 该对象b1具有声明的类型unsigned char[n].因此,它的有效访问类型也是unsigned char[n] …

c standards strict-aliasing language-lawyer

20
推荐指数
1
解决办法
399
查看次数

标签 统计

c ×1

language-lawyer ×1

standards ×1

strict-aliasing ×1