c - 具有文件范围的 C 结构
问题描述
问题:在文件范围内声明为静态的结构上的标记是否与文件私有的实际结构变量的声明方式相同?或者结构标签在文件中是否通用?
这个问题来自我在使用 MSVS2019 调试器时遇到的一个问题,它向我显示了某些文件中的错误值和结构成员名称。(如果您有兴趣,可以在此处阅读有关该错误的信息:Visual Studio 2019 调试器问题)这些文件都是从原始文件中克隆的,并且都具有以下内容:
static struct MyPrivateData_s
{
char *szData[64];
} myData;
static int myCount;
结构的实际成员因文件而异,每个文件的值也大不相同。
我知道声明为静态的变量,但在源文件中的任何函数之上都具有“文件范围”——仅对该文件是全局的。我很确定 VS 调试系统有问题,但这让我想知道静态存储类如何(或什至)如何影响结构标签。
如果标签被视为结构的名称和其他变量,那么它对文件是私有的。但是,如果对标签进行不同的处理,则可能会触发 VS 错误。请记住,我只询问结构标签,而不是实际结构变量的名称。了解typedef中的名称如何受“静态”影响也是一件好事。
我一直试图在我拥有的所有各种 C 参考文献中找到答案,并且可以在线找到,但我 (a) 不知道要问的正确问题和/或 (b) 不理解(或识别? ) 当我找到答案时。希望C大师可以帮助我。
FWIW,我认为在文件范围内遵循静态的任何内容都应限制在找到它的文件中。实际上,仅在文件中找到它的点以下。这就是我一直编码的方式,在这个调试器让我对此感到疑惑之前,我从未遇到过问题。谢谢!
我认为这可能会回答我的问题: 限制结构范围 ,即使它没有明确使用“标签”一词。相反,它似乎将标签称为“类型”,当以“结构”为前缀时,它就变成了。所以 static 没有效果,但是标签出现在 C 文件中而不是在公共头文件中的事实意味着标签是文件私有的。很抱歉打扰了。
解决方案
static
不影响结构标签或范围。
没有超出文件范围的范围(C 2018 6.2.1 1)。不同范围的标识符可以通过链接(6.2.2 1)引用同一个对象。如果不同的作用域在不同的翻译单元中,如果标识符有外部链接,则它们可以引用同一个对象。
结构标签没有链接(6.2.2 6:“以下标识符没有链接:声明为对象或函数以外的任何东西的标识符;……”)因此,不同翻译单元中的结构标签引用不同的实体。
这意味着不同翻译单元中的结构类型是不同的类型。然后有人会想知道如何在不同的翻译单元中使用相同的结构。根据 6.2.7 1,不同翻译单元中的结构类型可能是兼容的。对于结构,兼容性在很大程度上需要相同的定义,并有一些余量,例如可能省略标签。
声明中的存在static
(但不在[
and内部]
)会影响对象和函数的链接(6.2.2 3)和存储持续时间(6.2.4 3)。
这回答了这个问题:
问题:在文件范围内声明为静态的结构上的标记是否与文件私有的实际结构变量的声明方式相同?或者结构标签在文件中是否通用?
static
既不影响结构标签也不影响范围。它影响对象和函数标识符是否可以由于链接而不是范围而跨翻译单元相关。
typedef
名称是别名。
了解 typedef 中的名称如何受“静态”影响也是一件好事。
C 2018 6.7.8 3 说“...... typedef 声明不引入新类型,只是指定类型的同义词......”如上所述,static
仅影响对象和函数;它不影响类型或类型名称。
推荐阅读
- android - bitmapFactoryOptions.outWidth 和 Height 返回 -1
- javascript - 模拟由 Redux Provider 组件封装的 React 组件函数
- go - 对结构字段进行持久更改*并且*满足 Writer 接口?
- ember.js - EmberJS“详细信息”页面自动获取模型 - 这正常吗?
- javascript - 解析文件并创建符合特定条件的键值对
- java - 从命令行启动时,Spring Batch 不产生日志输出
- android - 为什么Android Studio arm64系统镜像很慢?
- node.js - 如何修复节点中注释长度无效的无效 zip 文件(供 yauzl 等严格库使用)
- php - Laravel 5.6 auth 指令不适用于某些视图
- r - 如何检查列表是否包含`NA`?