需要将 for 循环的上限保存在额外的变量中吗?
Needs upper bound in for loop to be saved in extra variable?
我经常在旧代码中看到这一点
DWORD num = someOldListImplementation.GetNum();
for (DWORD i = 0; i < num; i++)
{
someOldListImplementation.Get(i);
}
而不是
for (DWORD i = 0; i < someOldListImplementation.GetNum(); i++)
{
someOldListImplementation.Get(i);
}
我想第一个实现应该防止在每个周期调用 GetNum()
。但是,是否存在 C++11 中的编译器对第二个代码片段进行一些优化从而使 num
变量过时的情况?
我应该总是喜欢第一个实现吗?
如果该问题 100% 重复另一个问题,请告诉我并关闭此问题。没问题。
C++(本例中为 C++11)标准 似乎 没有为此留出太多空间。它在 6.5.3 The for statement /1
中明确指出(我的重点):
the condition specifies a test, made before each iteration, such that the loop is exited when the condition becomes false;
然而,如1.9 Program execution /1
所述:
Conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.
This provision is sometimes called the "as-if" rule, because an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program.
因此,如果一个实现可以确定来自 GetNum()
的 return 值在循环期间不会改变,它可以非常自由地优化除第一个调用之外的所有调用。
实施是否 可以 确定取决于很多事情,而且事情的数量似乎随着标准的每次新迭代而扩展。我正在考虑的是波动性、多线程访问、constexpr
等等。
您可能不得不 努力 通知编译器可以自由地执行此操作(而且,即便如此,也不是 必需的 这样做)。
我在您的第一个代码示例中看到的唯一问题是 num
可能存在的时间超过必要的时间(如果它存在的原因只是为了管理此循环)。然而,这可以很容易地通过明确限制范围来解决,例如使用“small-change”:
{
DWORD num = someOldListImplementation.GetNum();
for (DWORD i = 0; i < num; i++)
{
someOldListImplementation.Get(i);
}
}
// That num is no longer in existence.
或将其合并到 for
语句本身:
for (DWORD num = someOldListImplementation.GetNum(), i = 0; i < num; ++i)
{
someOldListImplementation.Get(i);
}
// That num is no longer in existence.
我的问题的确切答案是使用
for (auto i = 0, num = x.GetNum(); i < num; ++i)
{
}
因为
- 它阻止在每个周期调用
GetNum()
- 变量
num
没有暴露在循环外
感谢用户 Nawaz!
我也用++i代替了i++。原因:https://www.quora.com/Why-doesnt-it-matter-if-we-use-I++-or-++I-for-a-for-loop
我经常在旧代码中看到这一点
DWORD num = someOldListImplementation.GetNum();
for (DWORD i = 0; i < num; i++)
{
someOldListImplementation.Get(i);
}
而不是
for (DWORD i = 0; i < someOldListImplementation.GetNum(); i++)
{
someOldListImplementation.Get(i);
}
我想第一个实现应该防止在每个周期调用 GetNum()
。但是,是否存在 C++11 中的编译器对第二个代码片段进行一些优化从而使 num
变量过时的情况?
我应该总是喜欢第一个实现吗?
如果该问题 100% 重复另一个问题,请告诉我并关闭此问题。没问题。
C++(本例中为 C++11)标准 似乎 没有为此留出太多空间。它在 6.5.3 The for statement /1
中明确指出(我的重点):
the condition specifies a test, made before each iteration, such that the loop is exited when the condition becomes false;
然而,如1.9 Program execution /1
所述:
Conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.
This provision is sometimes called the "as-if" rule, because an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program.
因此,如果一个实现可以确定来自 GetNum()
的 return 值在循环期间不会改变,它可以非常自由地优化除第一个调用之外的所有调用。
实施是否 可以 确定取决于很多事情,而且事情的数量似乎随着标准的每次新迭代而扩展。我正在考虑的是波动性、多线程访问、constexpr
等等。
您可能不得不 努力 通知编译器可以自由地执行此操作(而且,即便如此,也不是 必需的 这样做)。
我在您的第一个代码示例中看到的唯一问题是 num
可能存在的时间超过必要的时间(如果它存在的原因只是为了管理此循环)。然而,这可以很容易地通过明确限制范围来解决,例如使用“small-change”:
{
DWORD num = someOldListImplementation.GetNum();
for (DWORD i = 0; i < num; i++)
{
someOldListImplementation.Get(i);
}
}
// That num is no longer in existence.
或将其合并到 for
语句本身:
for (DWORD num = someOldListImplementation.GetNum(), i = 0; i < num; ++i)
{
someOldListImplementation.Get(i);
}
// That num is no longer in existence.
我的问题的确切答案是使用
for (auto i = 0, num = x.GetNum(); i < num; ++i)
{
}
因为
- 它阻止在每个周期调用
GetNum()
- 变量
num
没有暴露在循环外
感谢用户 Nawaz!
我也用++i代替了i++。原因:https://www.quora.com/Why-doesnt-it-matter-if-we-use-I++-or-++I-for-a-for-loop