相关疑难解决方法(0)

便携式数据重新解释

我想以便携方式(C99)将一种类型的数据重新解释为另一种类型.我不是在谈论铸造,我想重新解释一些给定的数据.此外,通过便携式我的意思是它不会破坏C99规则 - 我并不是说重新解释的值在所有系统上都是相同的.

我知道3种不同的重新解释数据的方法,但其中只有两种是可移植的:

  1. 这不是便携式的 - 它打破了严格的别名规则.

    /* #1 Type Punning */
    
    float float_value = 3.14;
    int *int_pointer = (int *)&float_value;
    int int_value = *int_pointer;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 这是依赖于平台的,因为它int在写入之后从联合中读取值float.但它不会破坏任何C99规则,所以它应该工作(如果sizeof(int) == sizeof(float)).

    /* #2 Union Punning */
    
    union data {
      float float_value;
      int int_value;
    };
    
    union data data_value;
    data_value.float_value = 3.14;
    int int_value = data_value.int_value;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 应该没问题,只要 sizeof(int) == sizeof(float)

    /* #3 Copying */
    
    float float_value = 3.14;
    int int_value = …
    Run Code Online (Sandbox Code Playgroud)

c type-punning

14
推荐指数
1
解决办法
2860
查看次数

使用指向union的不同元素的指针作为参数调用函数是不确定的行为?

在使用-O1-O2(包括gcc和clang)编译后,此代码打印不同的值:

#include <stdio.h>

static void check (int *h, long *k)
{
  *h = 5;
  *k = 6;
  printf("%d\n", *h);
}

union MyU
{
    long l;
    int i;
};

int main (void)
{
  union MyU u;
  check(&u.i, &u.l);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我认为它应该是未定义的行为,因为指针别名,但我无法确切地指出代码的哪一部分是被禁止的.

它写入一个union元素然后从另一个读取,但是根据允许的缺陷报告#283.通过指针而不是直接访问union元素时是UB吗?

这个问题类似于通过指针访问C联盟成员,但我认为其中一个从未得到完全回答.

c undefined-behavior unions language-lawyer type-punning

11
推荐指数
1
解决办法
247
查看次数

将指向同一联合成员​​的两个指针传递给函数是否违反了严格的别名规则?

注意:学习严格的别名规则。请耐心等待。

代码示例(t935.c):

#include <stdio.h>

int f(int* pi, double* pd)
{
    *pi = 13;
    *pd = 7E-323;
    return *pi;
}

int main(void)
{
    union { int i; double d; } u;
    printf("%d\n", f(&u.i, &u.d));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

调用:

$ gcc t935.c -Wall -Wextra -std=c11 -pedantic  && ./a.exe
14

$ gcc t935.c -Wall -Wextra -std=c11 -pedantic -O2 && ./a.exe
13

$ gcc t935.c -Wall -Wextra -std=c11 -pedantic -O2 -fno-strict-aliasing && ./a.exe
14
Run Code Online (Sandbox Code Playgroud)

问题:将指向同一联合成员​​的两个指针传递给函数是否违反了严格的别名规则?

这个问题源于Unions 和 type-punning

UPD20210901

如果在全局范围内定义联合类型会发生什么?

对于“u …

c pointers constraints strict-aliasing c11

3
推荐指数
1
解决办法
65
查看次数

我可以为一个联盟成员分配一个值并从另一个联盟成员中读取相同的值吗?

基本上,我有一个

struct foo {
        /* variable denoting active member of union */
        enum whichmember w;
        union {
                struct some_struct my_struct;
                struct some_struct2 my_struct2;
                struct some_struct3 my_struct3;
                /* let's say that my_struct is the largest member */
        };
};

main()
{
        /*...*/
        /* earlier in main, we get some struct foo d with an */
        /* unknown union assignment; d.w is correct, however */
        struct foo f;
        f.my_struct = d.my_struct; /* mystruct isn't necessarily the */
                                /* active member, but is …
Run Code Online (Sandbox Code Playgroud)

c struct unions language-lawyer

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