Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0000686 [1003.1(2008)/Issue 7] System Interfaces Editorial Clarification Requested 2013-05-02 03:03 2019-06-10 08:55
Reporter dalias View Status public  
Assigned To ajosey
Priority normal Resolution Accepted As Marked  
Status Closed  
Name Rich Felker
Organization musl libc
User Reference
Section clock
Page Number unknown
Line Number unknown
Interp Status ---
Final Accepted Text Note: 0001614
Summary 0000686: Application usage for clock() conflicts with normative text
Description "If the processor time used is not available or its value cannot be represented, the function shall return the value (clock_t)-1."

vs

"The value returned by clock() may wrap around on some implementations. For example, on a machine with 32-bit values for clock_t, it wraps after 2147 seconds or 36 minutes."

The former (aligned with ISO C) requires unrepresentable time values to result in (clock_t)-1; the latter seems to permit implementations to instead truncate the value.

What's worse, if the value is truncated and clock_t is a signed type, the recommended application usage (subtracting clock_t values to measure intervals) causes the application to invoke undefined behavior via integer overflow. In particular, if the initial call to clock() returned A>0 (by virtue of some processor time having been consumed before the start of main() or the point of first measurement), and a subsequent call returned B=INT_MIN just after overflow, then the recommended practice of computing B-A invokes undefined behavior.

Note that the issue is exacerbated by the XSI requirement that CLOCKS_PER_SEC be 1000000, which makes overflow on 32-bit systems the norm rather than the exception.
Desired Action Resolve the issue in some way. This may require consulting with the ISO C committee since it seems that the path of codifying existing practice would conflict with a strict interpretation of the C standard as written, and the latter does not reflect what would be desirable to applications.

If wrapping is to be permitted, then the application usage should be updated to avoid invoking undefined behavior. At present, there is no way for applications to work around the issue because there is no way to determine the numeric limits of the clock_t type if it's a signed type, meaning there is (1) no way to predict whether subtraction will overflow, and (2) no way to convert to the corresponding unsigned type to safely perform the subtraction with modular arithmetic. (Conversion to a larger unsigned type like uintmax_t will yield the wrong results.) I see several possible solutions:

1. Defining limit macros for clock_t.
2. Defining a new type uclock_t that's the corresponding unsigned type (possibly the same on implementations where clock_t itself is unsigned).
3. Requiring clock_t to be unsigned if it can wrap. (But this conflicts with existing practice on some implementations, and the implementors are reportedly unwilling to change this due to C++ ABI/name-mangling compatibility issues and possibly other issues.)
Tags c99, tc2-2008
Attached Files

- Relationships
related to 0000703Applied 1003.1(2013)/Issue7+TC1 Add errno values for clock 

-  Notes
(0001614)
geoffclare (manager)
2013-05-17 11:43
edited on: 2013-05-17 16:05

At page 665 line 22541 section clock, insert a new first paragraph
in the APPLICATION USAGE section:

    In programming environments where clock_t is a 32-bit integer type
    and CLOCKS_PER_SEC is one million, clock() will start failing in
    less than 36 minutes of processor time for signed clock_t, or 72
    minutes for unsigned clock_t. Applications intended to be portable
    to such environments should use times() instead (or clock_gettime()
    with CLOCK_PROCESS_CPUTIME_ID, if supported).

At page 665 line 22545 section clock, delete:

    The value returned by clock() may wrap around on some
    implementations. For example, on a machine with 32-bit values for
    clock_t, it wraps after 2147 seconds or 36 minutes.

At page 665 line 22552 section clock, add clock_getres() and times() to
the SEE ALSO list.

(0001615)
dalias (reporter)
2013-05-17 14:03

I'm not opposed to this change, but it's definitely not codifying existing practice (which is to wrap), and it also makes the clock() interface rather useless on 32-bit systems.

It would be nice if clock_gettime could be recommended instead of times as the alternative, since times potentially has the same issue as clock, but it seems CLOCK_CPUTIME_CLOCKID is still not mandatory.
(0001616)
geoffclare (manager)
2013-05-17 16:07

We are constrained by the C Standard here. Implementations where
clock() wraps do not conform to the C Standard. (And if they
claim to conform, they have a bug.)

I have updated Note: 0001614 to mention clock_gettime().
(0002219)
nick (manager)
2014-04-10 15:02

Discussed by C committee in Chicago meeting:

clock overflow problems 
Tied to Austin Group Defect #686.  The basic question revolves around what happens if more 
processor time elapses than can be fit into a variable of type clock_t.  That seems to imply that 
the function must fail and return (clock_t)‐1. However many implementations ignore that, and 
simply truncate the value, returning the lowermost bits  of the actual value. 
 
Committee Discussion:  The overflow issue does not seem to be discussed in the Suggested TC, 
and it needs more work.

- Issue History
Date Modified Username Field Change
2013-05-02 03:03 dalias New Issue
2013-05-02 03:03 dalias Status New => Under Review
2013-05-02 03:03 dalias Assigned To => ajosey
2013-05-02 03:03 dalias Name => Rich Felker
2013-05-02 03:03 dalias Organization => musl libc
2013-05-02 03:03 dalias Section => clock
2013-05-02 03:03 dalias Page Number => unknown
2013-05-02 03:03 dalias Line Number => unknown
2013-05-16 15:45 nick Tag Attached: c99
2013-05-17 11:43 geoffclare Note Added: 0001614
2013-05-17 14:03 dalias Note Added: 0001615
2013-05-17 16:05 geoffclare Note Edited: 0001614
2013-05-17 16:07 geoffclare Note Added: 0001616
2013-05-23 15:59 msbrown Tag Attached: tc2-2008
2013-05-23 16:00 msbrown Interp Status => ---
2013-05-23 16:00 msbrown Final Accepted Text => Note: 0001614
2013-05-23 16:00 msbrown Status Under Review => Resolved
2013-05-23 16:00 msbrown Resolution Open => Accepted As Marked
2013-06-13 16:26 nick Relationship added related to 0000703
2014-04-10 15:02 nick Note Added: 0002219
2019-06-10 08:55 agadmin Status Resolved => Closed


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker