2

说我有这个功能:

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;
}

编译时有区别吗?

4

4 回答 4

6

这主要是一个见仁见智的问题。IMO 第二种形式更好,因为它总是提供返回值。如果您修改函数以在 else 子句中执行不同的操作,您可能会忘记添加返回值。在上面的示例中,生成的代码是相同的。

于 2013-06-18T11:06:54.637 回答
4

效率不是问题,不。一个半体面的编译器会知道该怎么做。而对于这个简单的功能,逻辑上应该是一样的。但是对于更大的函数,有更多的逻辑,第二个稍微好一点,因为它保证函数总是返回。

要么,要么更喜欢单点返回(尽管函数相对较小,但这并不一定适用于此)。这可以帮助编译器生成更好、更高效的代码,在某些情况下(多个返回语句阻碍 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;
}
于 2013-06-18T11:08:51.320 回答
1

不,编译器的语义分析,以及之后的优化器,都会产生相同的目标代码。

于 2013-06-18T11:09:35.117 回答
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在这种情况下使用并不会对性能产生太大影响。

于 2013-06-18T11:25:02.570 回答