Tôi đã kiểm tra các câu hỏi tương tự trên trang web, nhưng tôi không thể tìm thấy bất kỳ điều gì phù hợp với kịch bản của tôi ở đây. Đây là mã tôi đang cố gắng chạy (yêu cầu C++ 14):Tại sao tối ưu hóa -O2 hoặc cao hơn trong clang phá vỡ mã này?
#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);
}
}
Đây là lớp đếm ngược đơn giản mà tôi đã viết cho một trong các dự án của mình. Mã khách hàng trong main()
là khá tự giải thích, nó sẽ xuất ra một đếm ngược từ 10 đến 0, và sau đó thoát khỏi chương trình. Với không tối ưu hóa hoặc -O
/-O1
, nó không chính xác rằng:
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
Nhưng nếu tôi đẩy mạnh công tác tối ưu hóa để> = -O2
, chương trình chỉ giữ xuất ra 10, và chạy mãi mãi. Đếm ngược chỉ đơn giản là không hoạt động, nó bị mắc kẹt ở giá trị bắt đầu.
Tôi đang sử dụng Xcode mới nhất trên OS X. clang --version
nói Apple LLVM version 7.3.0 (clang-703.0.31)
.
Phần lạ là mã của tôi không chứa bất kỳ vòng lặp tự viết nào, hành vi không xác định hoặc bất kỳ thứ gì giống như vậy, nó chỉ là các cuộc gọi thư viện chuẩn, vì vậy rất kỳ lạ là tối ưu hóa nó.
Bất kỳ ý tưởng nào?
PS: Tôi chưa thử trên các trình biên dịch khác, nhưng tôi sắp sửa. Tôi sẽ cập nhật câu hỏi với những kết quả đó.
Mức tối ưu hóa không được thực sự phá vỡ hành vi của mã của bạn trừ khi bạn giới thiệu hành vi không xác định ở đâu đó. –
Có, nhưng tôi không thực sự thấy nó có thể ở đâu. Nếu đó là, nó phải là một cái gì đó rất tinh tế mà tôi không nhận thấy. – adam10603
Lưu ý đối với những người cố gắng tạo lại vấn đề: mã này cần phải được biên dịch bằng '-std = C++ 14' hoặc cao hơn. – zwol