是否可以防止在Objective-C中污染POSIX符号名称?

布赖恩·阿姆斯特朗

我在Xcode / Objective-C中遇到了某种意外的行为。我知道可能不建议这样做,但是如果我想struct in_addr在.m文件中创建自己的文件,似乎不可以。这意味着Objective-C中的名称空间和符号污染有些奇怪。这似乎适用于许多其他网络类型,也可能适用于其他POSIX-y。

我想出了一个非常基本的示例来演示此行为。请注意,此代码段是.m文件的全部内容。

#define _SYS_SOCKET_H_
#define _NETINET_IN_H_
#include <stdint.h>

struct in_addr {
  uint32_t foo;
};

这产生了构建错误Redefinition of 'in_addr'

这意味着关于Objective-C的一些相当奇怪的事情。对于初学者,我不希望<stdint.h>引入任何网络类型。但是即使允许,首先定义也_NETINET_IN_H_应阻止的定义struct in_addr但是,即使如此,该代码仍拒绝构建。

是否有可能以某种方式放弃这种强制的符号可见性?是否有包含的符号列表?这种行为是否有充分的理由?

编辑:陌生人仍然,如果我删除<stdint.h>并将其更改uint32_tint,这实际上可以编译。

查尔斯·斯特斯特卡

如果进入“报表”导航器并阅读该clang工具发出的完整错误,您将看到一个大提示:

In module 'Darwin' imported from /Users/csrstka/Desktop/asdfasdf/asdfasdf/main.m:1:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/netinet/in.h:302:12: note: field has name 's_addr' here
    in_addr_t s_addr;

如您所见,现有资源in_addr来自Darwin模块,由于模块的一部分,#include隐含导入如果您转到Xcode中的产品>执行操作>预处理,则会看到此内容-而不是复制已导入的所有标头,只有一行关于import stdint.hDarwinDarwin.C.stdint

基本上,模块有一些用途。它们通过减少多余的编译任务来缩短编译时间,并且防止人们通过#defines弄乱您的库标头,就像您尝试做的那样。;-)有关Objective-C模块,其工作方式以及其背后的原理的更多信息,请参见以下链接:

https://clang.llvm.org/docs/Modules.html#introduction

您的问题特别有趣的是以下摘录:

模块的主要用户级别功能是导入操作,该操作提供对软件库API的访问。但是,当今的程序广泛使用#include,并且假设所有这些代码都会在一夜之间发生更改是不现实的。相反,模块会自动将#include指令转换为相应的模块导入。例如,include指令

#include <stdio.h>

将自动映射到模块std.io的导入。即使使用该语言的特定导入语法,此特定功能对于采用和向后兼容性也很重要:#include自动转换为导入使应用程序能够获得模块的好处(对于所有启用了模块的库),而无需更改应用程序本身。因此,用户可以轻松地在一个编译器中使用模块,而回退到其他编译器的预处理器包含机制。

然后:

如果将模块的任何子模块导入程序的任何部分,则整个顶级模块都被视为程序的一部分。结果,Clang可能会诊断未导入的子模块中声明的实体与当前翻译单元中声明的实体之间的冲突,并且Clang可能会基于未导入的子模块中的知识进行内联或虚拟化。

或者,如果您希望关闭它们并获得更传统的类似C的行为,则可以Enable Modules (C and Objective-C)在Xcode的Build Settings中简单地设置为No,或者-fmodules如果使用命令行,则不带标志即可进行编译

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

是否可以防止Javascript中的popstate?

单个令牌是否可以防止RESTful API中的csrf?

Spring中的SimpleJdbcTemplate是否可以防止SQL注入?

是否可以防止Windows 10 uwp中的锁定屏幕?

是否可以防止从共享URL中剥离查询参数?

是否可以防止用户在后台运行C ++程序?

持有C ++参考是否可以防止变量被破坏?

在vim中,当我退出编辑模式时,是否可以防止插入符号移回?

在 Azure DevOps Server 2020 中,是否可以防止 Checkout 任务每次使用不同的名称?

我可以防止扩展导出到Objective-C的Swift标头吗?

是否可以防止Matlab定义覆盖函数名称的变量?

XML解析器是否可以防止.NET Core中的XML外部实体(XML)注入?

对象中正在运行的线程是否可以防止在Java中对其进行垃圾回收?

是否可以防止用户修改CUPS中的打印机选项?

外部引用结构中的字段是否可以防止对该结构进行垃圾回收?

是否可以防止CSS中带连字符的单词之间出现换行符?

从DOM中删除元素时,是否可以防止自动删除JQuery数据?

如果模板中不存在ng-content,是否可以防止创建子组件?

是否可以防止闭包捕获TypeScript中的外部变量?

在 Fullcalendar 中,是否可以防止事件 'foo' 与事件 'bar' 重叠,但允许它与事件 'quux' 重叠?

是否可以防止ReactJS中的单个组件实现Materialise CSS?

是否可以防止用户在Ubuntu 12.04 LTS中打开/保存文件对话框

在这种情况下,C#泛型是否可以防止结构自动装箱?

是否可以防止gtest(C ++)捕获异常和分段错误?

UITableViewCell中的UITextView可以防止Segue

在BAZEL中,是否有一种方法可以防止依赖C / C ++头传播到依赖库?

当我在《 Dragon NaturallySpeaking》中单独说出这个词时,是否可以防止该词被听写?

运行多个测试程序集时,“-workers:1”是否可以防止nunit3-console中的并行化?

当水平方向的图例方向为水平时,是否可以防止图例上的图例向上移动到图表中?