我查看了网站上的类似问题,但没有找到与我的情况相匹配的内容。这是我试图运行的代码(需要C++14):
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
class countdownTimer {
public:
using duration_t = chrono::high_resolution_clock::duration;
countdownTimer(duration_t duration) : duration{ duration }, paused{ true } {}
countdownTimer(const countdownTimer&) = default;
countdownTimer(countdownTimer&&) = default;
countdownTimer& operator=(countdownTimer&&) = default;
countdownTimer& operator=(const countdownTimer&) = default;
void start() noexcept {
if (started) return;
startTime = chrono::high_resolution_clock::now();
endTime = startTime + duration;
started = true;
paused = false;
}
void pause() noexcept {
if (paused || !started) return;
pauseBegin = chrono::high_resolution_clock::now();
paused = true;
}
void resume() noexcept {
if (!paused || !started) return;
auto pauseDuration = chrono::high_resolution_clock::now() - pauseBegin;
startTime += pauseDuration;
endTime += pauseDuration;
paused = false;
}
double remainingSeconds() const noexcept {
auto ret = double{ 0.0 };
if (!started) ret = chrono::duration_cast<chrono::duration<double>>(duration).count();
else if (paused) ret = chrono::duration_cast<chrono::duration<double>>(duration - (pauseBegin - startTime)).count();
else ret = chrono::duration_cast<chrono::duration<double>>(duration - (chrono::high_resolution_clock::now() - startTime)).count();
return (ret < 0.0) ? 0.0 : ret;
}
duration_t remainingTime() const noexcept {
auto ret = duration_t{ 0ms };
if (!started) ret = chrono::duration_cast<duration_t>(duration);
else if (paused) ret = chrono::duration_cast<duration_t>(duration - (pauseBegin - startTime));
else ret = chrono::duration_cast<duration_t>(duration - (chrono::high_resolution_clock::now() - startTime));
return (ret < 0ms) ? 0ms : ret;
}
bool isPaused() const noexcept { return paused; }
bool hasFinished() const noexcept { return remainingTime() == 0s; }
void reset() noexcept {
started = false;
paused = true;
}
private:
chrono::high_resolution_clock::time_point startTime;
chrono::high_resolution_clock::time_point endTime;
chrono::high_resolution_clock::time_point pauseBegin;
duration_t duration;
bool paused;
bool started;
};
int main() {
countdownTimer timer(10s);
timer.start();
while (!timer.hasFinished()) {
cout << timer.remainingSeconds() << endl;
this_thread::sleep_for(1s);
}
}
这是我为我的一个项目编写的一个简单的倒计时器类。在main()
中的客户端代码非常容易理解,它应该输出从10到0的倒计时,然后退出程序。没有任何优化或-O
/-O1
,它就可以完美地实现这个功能。
10
8.99495
7.98992
6.9849
5.97981
4.9748
3.96973
2.9687
1.9677
0.966752
Program ended with exit code: 0
但是,如果我把优化提升到 >= -O2,程序将一直输出10,并永远运行。倒计时根本不起作用,它被卡在起始值处。我正在使用最新的OS X上的Xcode。clang --version命令显示Apple LLVM版本7.3.0(clang-703.0.31)。奇怪的是,我的代码不包含任何奇怪的自编写循环、未定义的行为或类似的内容。它几乎只是标准库的调用,所以很奇怪优化会破坏它。有任何想法吗?注:我还没有在其他编译器上尝试过,但我即将尝试。我将在问题中更新这些结果。