Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么要使用';函数地址==NULL';而不是';假';?_C++_C_Deobfuscation - Fatal编程技术网

C++ 为什么要使用';函数地址==NULL';而不是';假';?

C++ 为什么要使用';函数地址==NULL';而不是';假';?,c++,c,deobfuscation,C++,C,Deobfuscation,浏览一些遗留代码,我发现了这样的功能: static inline bool EmptyFunc() { return (void*) EmptyFunc == NULL; } 与此有什么区别: static inline bool EmptyFunc() { return false; } 这段代码是在几个不同的平台下编译的,比如PS2,Wii,PC。。。是否有任何理由使用第一个函数?比如更好的优化或者避免一些奇怪的编译器错误行为?从语义上讲,这两个函数都是相同的:它们总是

浏览一些遗留代码,我发现了这样的功能:

static inline bool EmptyFunc()
{
    return (void*) EmptyFunc == NULL;
}
与此有什么区别:

static inline bool EmptyFunc()
{
    return false;
}

这段代码是在几个不同的平台下编译的,比如PS2,Wii,PC。。。是否有任何理由使用第一个函数?比如更好的优化或者避免一些奇怪的编译器错误行为?

从语义上讲,这两个函数都是相同的:它们总是返回false*。标准完全允许将第一个表达式折叠为常量值“false”,因为它不会改变任何可观察到的副作用(没有副作用)。因为编译器可以看到整个函数,所以它也可以自由地优化掉对它的任何调用,并用一个常量“false”值替换它

也就是说,第一种形式中没有“通用”值,这可能是程序员的错误。唯一的可能性是它利用特定编译器/版本中的某些特殊行为(或缺陷)。然而,我不知道目的是什么。如果您希望防止使用特定于编译器的属性进行内联,那么这是正确的方法——如果编译器发生更改,任何其他内容都很容易中断


(*这假设
NULL
从未定义为
EmptyFunc
,这将导致返回
true

严格来说,函数指针不能强制转换为空指针,然后发生的情况超出了标准的范围。C11标准将其列为J.5.7中的“通用扩展”(我怀疑这同样适用于C++)。因此,这两种情况的唯一区别在于前者是不可移植的

似乎前一个版本最有可能的原因是程序员或编译器感到困惑。我们可以肯定地说,由于缺少解释性的注释,程序员感到困惑/草率


将函数声明为
inline
,然后试图通过在代码中包含函数地址来欺骗编译器使其不内联代码,这实际上没有多大意义。所以我认为我们可以排除这个理论,除非程序员感到困惑,认为它是有意义的。

我认为这是因为如果你只是返回
false
,编译器就可以自由地优化掉这个函数。。。但是,任何实际使用它的地方都应该防止同样的优化。嗯。
EmptyFunc
在哪里使用?另外,为什么强制转换为
无效*
?这对于函数指针来说没有意义……只是猜测而已,但看起来它们试图迫使编译器生成函数的非内联版本。当您使用指向函数的指针时,可能会发生这种情况。
EmptyFunc
在用户输入注册过程中用作回调,该过程将遍历每个注册的回调,并在给定回调返回true时将相应事件标记为触发。@CaptainObvlious,在第一个函数中,没有任何东西可以阻止编译器在调用函数时优化函数。也许有一些编译器没有,但没有什么基本的东西阻止它。另一个选择可能是糟糕的编码。+1这也是我的感觉,这是为了解决编译器问题(我见过错误编译器更糟糕的解决方法,但至少代码是有文档记录的,不像这里!)。