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


10

我有一个*.cpp使用C ++编译的文件(不是C编译器)。包含函数依赖于强制转换(请参见最后一行),该强制转换似乎是在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文件中以使其定义为行为?


1
文件扩展名没有任何意义。仅当您将其编译为C或C ++时。
弗雷德里克

1
相应的类型不是彼此继承的,也没有关系,这在C ++中是未定义的
Daniel Stephens

1
通常,如果文件具有.c扩展名,则会自动调用C编译器。
Igor R.

1
我一直在用C ++代码来欺骗。不知道为什么它对您不起作用。在某处缺少标题?
user4581301

3
@DanielStephens此程序从不尝试取消引用指针。强制转换本身,可以取消引用-仅在某些时候。如果C端正确地将指针转换回实型,那么一切都应该没问题。如果这些类型具有不同的对齐要求,则可能会出现转换问题。
user7860670

Answers:


6

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

这是来自C ++引号(感谢@interjay和@VTT):

可以将对象指针显式转换为其他类型的对象指针。

这是C引号(感谢@StoryTeller),它允许这样做:

指向对象类型的指针可以转换为指向不同对象类型的指针。

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

这是POSIX报价,它允许这种特定情况:

SOCKADDR_IN结构是用来存储地址的互联网地址族。此类的指针应由应用程序强制转换struct sockaddr *以与套接字函数一起使用。

由于此函数(bind)是C标准库的一部分,所以内部发生的任何事情(特别是取消引用类型转换的指针)都没有未定义的行为。


要回答更一般的问题:

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


1
@interjay可以用标准引号(C或C ++都可以)支持吗?
SS安妮


1
@StoryTeller谢谢。不过,添加了HTTP版本。
SS安妮

2
可以说这是POSIX标准的缺陷-的第二个参数bind应该是a const void *,但是要bind早于voidC语言的存在(以及C ++的存在)。他们在某个时候对其进行了更新以添加const,但从未修复基本类型。
克里斯·多德

1
我可以推荐这个话题youtube.com/watch?v=_qzMpk-22cc我仍然不确定它是否可以验证答案,或者实际上是相反的说法:-o C ++是一场噩梦。哈哈
Daniel Stephens

-3

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

在C或C ++标准的某些部分以及实现的文档共同定义或描述一个动作,而其他部分将其描述为“未定义”的情况下,允许实现以最能满足其客户需求的方式处理代码,或者-对客户需求无动于衷-他们认为合适的任何时尚。该标准将此类事项视为其管辖范围之外的事实,并不意味着可以判断何时和/或如何声称实现适合各种目的的实现能够对其进行有意义的处理,但是有些编译器维护者对此表示赞同。


第一段:“ C和C ++代码之间的调用均会调用未定义的行为”即使存在“调用未定义的行为”之类的东西(没有),这仍然没有意义。
Lightness比赛于

第二段:不知道您要说什么。
Lightness比赛于

@LightnessRacesinOrbit我认为这个答案是我在问题中添加了[language-lawyer]标签的结果。我现在考虑得更好(答案往往太直白了)并删除了它。
SS安妮

1
@ JL2210我不认为这是你的错。
Lightness比赛于
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.