假设我有这样的函数:
inline bool fileExists(const char *name) {
FILE *file;
if (fopen_s(&file, name, "r") == 0)
{
fclose(file);
return true;
} else {
return false;
}
}
做上面那个好,还是做这个好?
inline bool fileExists(const char *name) {
FILE *file;
if (fopen_s(&file, name, "r") == 0)
{
fclose(file);
return true;
}
return false;
}
在编译时是否存在差异?
这主要是意见问题。在我看来,第二种形式更好,因为它总是提供返回值。如果在else子句中修改函数做一些不同的事情,您可能会忘记添加返回值。在上面的示例中,生成的代码是相同的。
效率不是问题。一个像样的编译器应该知道该怎么做。对于这个简单的函数,逻辑上应该是一样的。但是对于更大的函数,有更多的逻辑,第二种方法稍微好一些,因为它保证函数总是返回。
或者选择单点返回(这并不一定适用于这里,因为函数相对较小)。这可以帮助编译器生成更好、更高效的代码,在某些情况下(多个返回语句阻碍RVO):
inline bool fileExists(const char *name) {
FILE *file;
bool exists = false;
if (fopen_s(&file, name, "r") == 0)
{
fclose(file);
exists = true;
}
return exists;
}
不,编译器的语义分析,以及之后的优化器,将得到相同的目标代码。
在这种特殊情况下,绝对不是问题。fopen
将花费微秒(除非包含实际文件的目录没有缓存,在这种情况下需要几毫秒),并且您担心是否会有一个额外的跳转—可能是4-6个时钟周期。
一般来说,我更喜欢"一个返回语句",但它有时会变得相当混乱,在这种情况下,我更喜欢第二个选项。几乎总是,代码会变成这样,因为"编译器"也更喜欢单个出口点:
bool fileExists(const char *name) {
FILE *file;
bool ret_val;
if (fopen_s(&file, name, "r") == 0)
{
fclose(file);
ret_val = true;
goto end;
}
ret_val = false
end:
return ret_val;
}
有时候,如果代码非常复杂——特别是如果代码"开始很简单",然后变得复杂,编译器将从函数中获得多个返回点,但上面的场景是相当典型的。我并不是建议你在代码中使用goto
。编译器完全有能力做出改变]
哦,我怀疑在这种情况下使用inline
并不会对性能产生太大的影响。