通过将函数指针转换为 void 函数然后调用它来“丢弃”返回值是否是未定义的行为?

1 c casting function-pointers function undefined-behavior

说,像这样:

int SayHelloThenReturnTen(void) {
    puts("Hello world");
    return 10;
}
Run Code Online (Sandbox Code Playgroud)

后来:

((void(*)(void))SayHelloThenReturnTen)();
Run Code Online (Sandbox Code Playgroud)

那安全吗?通过强制转换为空指针来“丢弃”返回值是否安全?这是安全的跨平台,还是未定义的行为

Joh*_*ger 6

那安全吗?

将函数指针强制转换为任何函数指针类型是安全的。将结果转换回原始类型将产生一个等于原始指针的指针值。

它是不是安全的,但是,要调用通过类型与它所指向的功能不兼容的函数指针的函数。这在标准的第 6.3.2.3/8 段中有很清楚的规定:

指向一种类型函数的指针可以转换为指向另一种类型函数的指针,然后再返回;结果应与原始指针相等。如果使用转换后的指针调用类型与引用类型不兼容的函数,则行为未定义。

(强调)

通过强制转换为空指针来“丢弃”返回值是否安全?

你的例子没有证明这一点。相反,它演示了转换为具有void返回类型的函数指针类型。再次,演员是好的,但电话不是。

这是安全的跨平台,还是未定义的行为?

它是不安全的并且具有未定义的行为。而且,绝对得不到任何好处。如果您愿意,您可以简单地忽略函数的返回值。如果您试图消除有关这样做的编译器警告,那么,

  1. 考虑一下,也许编译器有道理,并且
  2. 如果你想传达给编译器,你真的要忽略的返回值,那么它是更清晰,更简单,安全地投对无效:

    (void) SayHelloThenReturnTen();
    
    Run Code Online (Sandbox Code Playgroud)

  • @9694,更快且不可靠并不比慢且正确更好。此外,如果使用三元有任何性能优势,那么它只是调用一个或另一个函数的总成本的一小部分。*并且*,使用三元,您可能会放弃使用“if”/“else”获得的优化,例如内联。一般来说,选择好的算法并编写清晰的代码。不要用这样的微观优化把事情搞得一团糟,除非你有充分的理由这样做(基于性能测量)。 (2认同)