对存在同名类型的变量使用 sizeof 是否定义良好?

2024-04-02

这是明确定义的行为还是未定义/以其他方式定义foo(数据类型或标识符)sizeof将在 ? 上运行?

typedef int foo;

int main(int argc, char *argv[])
{
    char foo;
    printf ("%u\r\n", sizeof(foo));
    return 0;
}

如果定义良好,有没有办法获得数据类型的大小foo不声明该类型的变量仅供使用sizeof on it?


C 没有显式作用域解析,因此标识符(变量名称、typedef 名称、结构名称等)可以重用并被覆盖当打开一个新的范围时。当重复使用标识符时,该标识符所持有的先前上下文将不再存在visible.

在您的特定代码中,范围typedef是全局的,因此 typedef 在编译包中的任何地方都可见。但是,您使用函数声明打开一个新作用域,并在该新作用域中定义一个变量,该变量使用与函数声明相同的标识符。typedef。现在,该标识符指的是变量而不是类型;意思是,直到变量的范围结束(函数结束),typedef是完全隐藏的。

回想一下,C 是线性编译的,因此您可以执行类似的操作来绕过所发生的屏蔽:

#include <stdio.h>
typedef int foo;

int main()
{
    printf ("%zu\n", sizeof (foo)); /* #1 */

    char foo;
    printf ("%zu\n", sizeof foo); /* #2 */

    return 0;
}

在第 1 点,请注意变量的范围char foo由于编译器尚未达到其声明,因此尚未打开。 (编译器要做的就是在堆栈上为变量分配空间)。

所以使用foo那时仍然参考全球定义的typedef.

当您点击 #2 时,变量已被声明,并且变量的生命周期已正式开始,这意味着该标识符现在用于不同的实体。它屏蔽了当前块作用域(由函数声明开始)的全局定义foo.

这是有据可查的行为;网上有 C 标准草案,但必须购买已发布的标准。草案第6.2.1条规定:

如果标识符指定同名的两个不同实体 空间,范围可能会重叠。如果是这样,一个实体的范围( 内部范围)将严格在另一个实体的范围之前结束 (外部范围)。在内部范围内,标识符指定 内部作用域中声明的实体;中声明的实体 外部作用域隐藏在内部作用域内(并且不可见)。source http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

请注意,这并不神奇或什么......这都是在编译时完成的。编译器有一个标识符表及其引用的内容,新的作用域会为这些创建新的表。碰巧的是,在上面代码中的第 1 点,编译器尚未用新的值填充表char foo(这是由于线性编译造成的)。所以当它翻译第一个时printf行,它会遍历所有活动范围以查找标识符foo,并看到typedef,并使用它。在第二次printf,它会查看所有活动范围并找到该标识符的最近使用情况foo并使用它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对存在同名类型的变量使用 sizeof 是否定义良好? 的相关文章

随机推荐