C++ clock() function stops at maximum value instead of rolling over - is this documented anywhere? - Stack Overflow

admin2025-04-16  6

I've tried to research this as thoroughly as I could but cannot find where this is documented anywhere. If anyone is aware of a resource that describes this behavior that would be very helpful to me.

In the legacy software I am working on, in C++ code, the function clock() is used to get the number of cycles since the program was started. The function clock() returns a clock_t. The type clock_t is defined as a long in time.h. Also in time.h, CLOCKS_PER_SEC is defined as 1000, so clock() is returning milliseconds. Using std::numeric_limits<clock_t>::max() and doing the math, the maximum value clock() can return is reached in ~24.9 days.

The legacy code was originally written assuming the next value clock() returns after it returns the maximum value would be 0. I attempted to research this assumption and was unable to find an answer. I then ran a test and let it run for 25 days and found, to my surprise, that clock() simply continues to return its maximum value once this number is reached. Unsurprisingly, this breaks the code horribly.

The situation has already been fixed - by creating a new timer solution based on std::chrono::steady_clock, which can return nanoseconds and rolls over after ~292 years. My question here is strictly trying to find documentation of this behavior of clock() simply stopping. I would like to be able to include this in my reporting of the issue.

Thanks in advance for any info.

I've tried to research this as thoroughly as I could but cannot find where this is documented anywhere. If anyone is aware of a resource that describes this behavior that would be very helpful to me.

In the legacy software I am working on, in C++ code, the function clock() is used to get the number of cycles since the program was started. The function clock() returns a clock_t. The type clock_t is defined as a long in time.h. Also in time.h, CLOCKS_PER_SEC is defined as 1000, so clock() is returning milliseconds. Using std::numeric_limits<clock_t>::max() and doing the math, the maximum value clock() can return is reached in ~24.9 days.

The legacy code was originally written assuming the next value clock() returns after it returns the maximum value would be 0. I attempted to research this assumption and was unable to find an answer. I then ran a test and let it run for 25 days and found, to my surprise, that clock() simply continues to return its maximum value once this number is reached. Unsurprisingly, this breaks the code horribly.

The situation has already been fixed - by creating a new timer solution based on std::chrono::steady_clock, which can return nanoseconds and rolls over after ~292 years. My question here is strictly trying to find documentation of this behavior of clock() simply stopping. I would like to be able to include this in my reporting of the issue.

Thanks in advance for any info.

Share Improve this question edited Feb 4 at 18:48 Dan B. asked Feb 3 at 23:37 Dan B.Dan B. 334 bronze badges 6
  • The implementation of the clock function varies based on the runtime/operating system. While it would seem that the appropriate thing to do would be for the clock function to return -1 if it detected a rollover, the implementation that your environment uses is using this behavior. – bogertron Commented Feb 3 at 23:54
  • 2 A signed type, like long cannot formally wrap around. And if it does that anyway, it will likely not end up as 0 but as a negative value. – BoP Commented Feb 4 at 0:06
  • You should tag this as C; that's where clock comes from. The C++ standard just incorporates the C requirements by reference. – Pete Becker Commented Feb 4 at 2:07
  • But the answer is that if the system clock isn't available or its value cannot be represented clock() returns clock_t)-1. See here. That link was the first hit when I googled std::clock. you must not have tried very hard. – Pete Becker Commented Feb 4 at 2:10
  • 4 @PeteBecker: That's actually out of date, though. C11 had that requirement, but C17 changed it to "If the processor time used is not available, the function returns the value (clock_t)(−1). If the value cannot be represented, the function returns an unspecified value." Thus bringing into compliance those implementations where it can wrap around; but it means that the "saturating" behavior of OP's implementation is legal too. – Nate Eldredge Commented Feb 4 at 4:12
 |  Show 1 more comment

1 Answer 1

Reset to default 3

It depends what version of the C or C++ standard your compiler claims to implement. The behavior of clock() is defined in the C standard, and incorporated by reference into the C++ standard.

In C11 and earlier (incorporated into C++17 and earlier), the behavior of clock() was defined as:

If the processor time used is not available or its value cannot be represented, the function returns the value (clock_t)(-1).

Overflow would correspond to "its value cannot be represented", so according to this standard, clock should be returning -1. Since you said clock_t is defined as long on your platform, which is a signed type, then -1 should not equal the maximum value, and so such behavior would be non-conformant. (However, it would if clock_t were an unsigned type, so you might want to double check that.)

In C17 and later (corresponding to C++20 and later), this was changed to:

If the processor time used is not available, the function returns the value (clock_t)(−1). If the value cannot be represented, the function returns an unspecified value.

This was probably intended to allow for the common behavior of clock wrapping around on overflow; but it means that your implementation's unusual "saturation" behavior is conformant as well. You'd be expected to look to the implementation's own documentation for an explanation of its behavior.

转载请注明原文地址:http://www.anycun.com/QandA/1744745257a87012.html