c - 为什么在一个函数中声明的 union 类型在另一个函数中使用是无效的?

标签 c function scope unions

当我阅读 ISO/IEC 9899:1999(参见:6.5.2.3)时,我看到了一个这样的例子(强调我的):

The following is not a valid fragment (because the union type is not visible within function f):

struct t1 { int m; };
struct t2 { int m; };
int f(struct t1 * p1, struct t2 * p2)
{
      if (p1->m < 0)
            p2->m = -p2->m;
      return p1->m;
}
int g()
{
      union {
            struct t1 s1;
            struct t2 s2;
      } u;
      /* ... */
      return f(&u.s1, &u.s2);
}

我测试时没有发现任何错误和警告。

我的问题是:为什么这个片段无效?

最佳答案

该示例试图预先说明段落1(强调我的):

6.5.2.3 ¶6

One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members.

因为 f 是在 g 之前声明的,而且未命名的 union 类型是 g 的本地类型,所以毫无疑问 union 类型是在 f 中不可见。

该示例没有显示 u 是如何初始化的,但假设最后写入成员的是 u.s2.m,该函数具有未定义的行为,因为它检查p1->m 公共(public)初始序列保证不生效。

反之亦然,如果在函数调用之前最后写入的是 u.s1.m,那么访问 p2->m 是未定义的行为。

请注意,f 本身并不是无效的。这是一个非常合理的函数定义。未定义的行为源于将 &u.s1&u.s2 作为参数传递给它。这就是导致未定义行为的原因。


<子> 1 - 我在引用 n1570 ,C11标准草案。但规范应该是相同的,仅需向上/向下移动一两段。

关于c - 为什么在一个函数中声明的 union 类型在另一个函数中使用是无效的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52511896/

相关文章:

c - 我如何了解这个不寻常角色的值(value)?里面有数字的方阵

javascript - jQuery 确认对话框 - 类冲突

python - 模块对象访问 Jupyter 笔记本单元中的 "global"值

visual-studio - Visual Studio Debugger 未在鼠标悬停时显示变量详细信息,因为它是 "out of context"

c - 编译时出现此错误,我不知道出了什么问题

c - C 编程 if else 语句遇到问题

mysql - 在 SQL 中,如何输出对多个列执行函数的列?

jQuery - 如何在其内部重复一个函数以包含嵌套文件

javascript - 使用 "let"关键字的 block 作用域

c - 在函数中返回指针时出现段错误