gpt4 book ai didi

c++ - 为什么 -O2 或更大的 clang 优化会破坏此代码?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:56:06 24 4
gpt4 key购买 nike

我在网站上查看了类似的问题,但在这里找不到与我的情况相符的任何问题。这是我要运行的代码(需要 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 --versionApple LLVM version 7.3.0 (clang-703.0.31)

奇怪的是我的代码不包含任何奇怪的自写循环、未定义的行为或类似的东西,它几乎只是标准库调用,所以优化破坏它是非常奇怪的。

有什么想法吗?

PS:我还没有在其他编译器上尝试过,但我即将尝试。我会用这些结果更新问题。

最佳答案

bool started 未初始化。如果您将它初始化为 false,它会与 -O2 一起工作:

live example

您可以使用 Undefined behavior sanitizer 找到这样的错误:

$ g++ -std=c++14 -O2 -g -fsanitize=undefined -fno-omit-frame-pointer main.cpp && ./a.out

main.cpp:18:9: runtime error: load of value 106, which is not a valid value for type 'bool'

关于c++ - 为什么 -O2 或更大的 clang 优化会破坏此代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38805335/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com