如果未定义的 C++ 行为符合 C 定义的行为会发生什么?

What happens if undefined C++ behaviour meets C defined behaviour?

我有一个用 C++(不是 C 编译器)编译的 *.cpp 文件。包含函数依赖于一个转换(见最后一行),它似乎是在 C 中定义的(如果我错了请更正!),但不是在 C++ 中用于这种特殊类型。

[...] C++ code [...]

struct sockaddr_in sa = {0};
int sockfd = ...;
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
bind(sockfd, (struct sockaddr *)&sa, sizeof sa);

[...] C++ code [...]

因为我在 C++ 文件中编译它,所以现在这是已定义还是未定义的行为?或者我需要将它移到 *.c 文件中,以使其定义行为吗?

这在 C++ 和 C 中都有定义。它不违反严格的别名规定,因为它不取消引用结果指针。

这是允许这样做的 quote from C++(感谢@interjay 和@VTT):

An object pointer can be explicitly converted to an object pointer of a different type.

这是允许这样做的quote from C(感谢@StoryTeller):

A pointer to an object type may be converted to a pointer to a different object type.

这些指定可以将一种指针类型转换为另一种指针类型(然后可选地转换回来)而不会产生任何后果。

这里是允许这种特定情况的 quote from POSIX

The sockaddr_in structure is used to store addresses for the Internet address family. Pointers to this type shall be cast by applications to struct sockaddr * for use with socket functions.

由于此函数 (bind) 是 C 标准库的一部分,因此无论内部发生什么(特别是取消引用类型转换指针)都没有未定义的行为。


回答更一般的问题:

C 和 C++ 是两种不同的语言。如果某些东西是在 C 中定义的,但不是在 C++ 中定义的,那么它是在 C 中定义的,但不是在 C++ 中定义的。两种语言之间的隐含兼容性不会改变这一点。如果您想使用在 C 中明确定义但在 C++ 中未定义的代码,则必须使用 C 编译器来编译该代码。

从各自标准的角度来看,C 和 C++ 代码之间的调用都会调用未定义的行为,但大多数平台都指定了此类内容。

如果 C 或 C++ 标准的某些部分和实现的文档一起定义或描述了一个操作,但其他部分将其描述为未定义,则允许实现以最能满足客户需求的任何方式处理代码或者——如果他们对客户的需求漠不关心——他们认为合适的任何时尚。该标准将此类事项视为其管辖范围之外的事实并不意味着对何时 and/or 声称适用于各种目的的实现应该如何有意义地处理它们做出任何判断,但一些编译器维护者认为它是一个神话确实。