为什么POSIX与ISO C标准相矛盾

时间:2016-06-06 15:17:32

标签: c sockets posix strict-aliasing type-punning

请参阅 http://pubs.opengroup.org/onlinepubs/009696699/basedefs/sys/socket.h.html

http://pubs.opengroup.org/onlinepubs/9699919799来自第7期 - 从2013年起仍然相同!)

sockaddr_storage意在转换为其他结构类型, 但这与ANSI和ISO C标准别名规则相矛盾 据我所知。 (可能无法访问对象 指向不兼容类型的指针,除了任何东西 可以通过3个char类型和结构访问 它的第一个成员是可以互换的。)

我知道使用套接字的做法存在很长时间 在C标准化之前,但POSIX应该符合 ISO C实际上与其手册中的标准相矛盾。 (甚至在 更新版本的POSIX。)

他们为什么一开始就这样做? 他们为什么不改变它?

2 个答案:

答案 0 :(得分:3)

标准中的严格别名规则约束用户代码,而不是实现代码。由于POSIX头文件和库是实现的一部分,因此POSIX和C标准之间不存在实际冲突。

在开源平台中,特别是在Linux中,C库和编译器由不同的团队开发,这使得实现者的生活变得困难,但这是他们关注的问题,而不是你的问题。例如,实现者可以:

  • 避免暴露标准之间的潜在冲突(即禁用严格别名优化);
  • 承认他们的实现不符合POSIX(并注意,例如,没有POSIX认证的Linux发行版);
  • 提供设施以确保潜在冲突的设施实际上不会发生冲突。从C标准的角度来看,这将是一个扩展。

最后一个选项是gcc和glibc团队如何解决sockaddr问题;见https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71255

答案 1 :(得分:2)

事实上,我认为这里没有违反严格别名规则的行为。是的,当你调用一个函数时,你将它转换为另一种类型,但谁说它必须通过这种类型的指针访问?

协议实现知道结构的正确类型,因此当它们访问结构时,它们会将其转换回正确的类型。此处的转换仅用于将指针从一个例程传递到另一个例程,但转换的类型不用于访问数据。