在一些遗留代码中浏览我发现了这样的功能:
static inline bool EmptyFunc()
{
return (void*) EmptyFunc == NULL;
}
与此有什么不同:
static inline bool EmptyFunc()
{
return false;
}
这个代码是为了在几个不同的平台上编译而创建的,比如PS2,Wii,PC ......有没有理由使用第一个函数?喜欢更好的优化还是避免一些奇怪的编译器错误行为?
答案 0 :(得分:10)
从语义上讲,两个函数都是相同的:它们总是返回false *。将第一个表达式折叠为常量值“false”是标准完全允许的,因为它不会改变任何可观察到的副作用(其中没有任何副作用)。由于编译器可以看到整个函数,因此它也可以自由地优化掉对它的任何调用,并用常量“false”值替换它。
也就是说,第一种形式中没有“一般”值,并且可能是程序员的错误。唯一的可能性是它利用特定编译器/版本中的某些特殊行为(或缺陷)。然而,到目前为止我还不知道。如果你希望使用特定于编译器的属性来防止内联是正确的方法 - 如果编译器发生变化,其他任何东西都容易破坏。
(*这假设NULL
永远不会被定义为EmptyFunc
,这会导致true
被返回。)。
答案 1 :(得分:3)
严格地说,函数指针可能不会转换为void指针,然后发生的事情超出了标准的范围。 C11标准将其列为J.5.7中的“通用扩展”(我怀疑在C ++中也是如此)。所以两种情况之间的唯一区别在于前者是不可移植的。
看起来,前一版本最可能的原因是一个混乱的程序员或一个混乱的编译器。我们可以肯定地说,由于缺乏解释性评论,程序员感到困惑/邋。。
将函数声明为inline
然后尝试通过在代码中包含函数地址来欺骗编译器而不是内联代码并没有多大意义。所以我认为我们可以排除这种理论,除非程序员当然感到困惑并认为它是有意义的。