说我有这个功能:
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;
}
编译时是否存在差异?
答案 0 :(得分:6)
这主要是一个意见问题。 IMO第二种形式更好,因为它总是会提供一个返回值。如果修改函数以在else子句中执行不同的操作,则可能忘记添加返回值。在上面的示例中,生成的代码是相同的。
答案 1 :(得分:4)
效率不是问题,不是。一个不太合适的编译器会知道该怎么做。对于这个简单的功能,逻辑上它应该是相同的。但是对于更大的函数,有更多的逻辑,第二个稍微好一点,因为它保证函数总是返回。
或者更喜欢单点返回(虽然功能相对较小,但这并不一定适用于此)。在某些情况下,这可以帮助编译器生成更好,更有效的代码(多个return语句阻碍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;
}
答案 2 :(得分:1)
不,编译器的语义分析以及之后的优化器将导致相同的目标代码。
答案 3 :(得分:1)
在这种特殊情况下,绝对肯定不是问题。 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
并不会对性能产生太大影响。