Ich überprüfte ähnliche Fragen auf der Website, aber ich konnte nichts finden, das meinem Szenario hier entspricht. Dies ist der Code I (erfordert C++ 14) laufen bin versucht:Warum bricht die Optimierung von o2 oder höher beim clang diesen Code?
#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);
}
}
Es ist eine einfache Countdown-Timer-Klasse, die ich für eine meiner Projekte geschrieben. Der Client-Code in main()
ist ziemlich selbsterklärend, es sollte einen Countdown von 10 bis 0 ausgeben und dann das Programm beenden. Ohne Optimierung oder -O
/-O1
, tut es genau das:
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
Aber wenn ich die Optimierung> = -O2
intensivieren, das Programm hält nur 10 ausgegeben wird, und läuft für immer. Der Countdown funktioniert einfach nicht, er bleibt beim Startwert hängen.
Ich verwende den neuesten Xcode auf OS X. clang --version
sagt Apple LLVM version 7.3.0 (clang-703.0.31)
. Der seltsame Teil ist, dass mein Code keine seltsamen selbstgeschriebenen Schleifen, undefiniertes Verhalten oder ähnliches enthält, es sind so ziemlich nur Standardbibliotheksaufrufe, es ist also sehr seltsam, dass die Optimierung es bricht.
Irgendwelche Ideen?
PS: Ich habe es nicht auf anderen Compilern versucht, aber ich bin dabei. Ich werde die Frage mit diesen Ergebnissen aktualisieren.
Optimierungsstufen sollten das Verhalten des Codes nicht beeinträchtigen, es sei denn, Sie haben irgendwo undefiniertes Verhalten eingeführt. –
Ja, aber ich sehe nicht wirklich, wo das sein könnte. Wenn das so ist, muss es etwas sehr Subtiles sein, das ich nicht wahrnehme. – adam10603
Hinweis für Personen, die versuchen, das Problem zu reproduzieren: Dieser Code muss mit '-std = C++ 14' oder höher kompiliert werden. – zwol