This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

### 3145. `file_clock` breaks ABI for C++17 implementations

Section: 29.7.6 [time.clock.file] Status: C++20 Submitter: Billy Robert O'Neal III Opened: 2018-07-26 Last modified: 2021-02-25

Priority: 1

View all issues with C++20 status.

Discussion:

It was pointed out in one of Eric's changes to libc++ here that P0355 adds `file_clock`, which is intended to be the clock used for `std::filesystem::file_time_type`'s clock.

Unfortunately, this is an ABI break for implementations that are already shipping C++17 filesystem that did not call their clock type `std::file_clock`. For example, MSVC++'s is called `std::filesystem::_File_time_clock`.

We can keep much the same interface of P0355 by making `file_clock` a typedef for an unspecified type. This technically changes the associated namespaces for expressions using that clock for the sake of ADL, but I can't imagine a user who cares, as clocks aren't generally called in ADL-able expressions, `duration`s and `time_point`s are.

Previous resolution [SUPERSEDED]:

> This wording is relative to N4750.

> 1. Change 29.2 [time.syn], header `<chrono>` synopsis, as indicated:

>    >     […]
>    >     // 29.7.6 [time.clock.file], classtype file_clock
>    >     classusing file_clock = unspecified;
>    >     […]

> 2. Change 29.7.6 [time.clock.file] as indicated:

>    > 23.17.7.5 Class Type `file_clock` [time.clock.file]

> 3. Change 29.7.6.1 [time.clock.file.overview], class `file_clock` synopsis, as indicated:

>    >     namespace std::chrono {
>    >       using file_clock = see below;
>    >       class file_clock {
>    >       public:
>    >         using rep = a signed arithmetic type;
>    >         using period = ratio<unspecified, unspecified>;
>    >         using duration = chrono::duration<rep, period>;
>    >         using time_point = chrono::time_point<file_clock>;
>    >         static constexpr bool is_steady = unspecified;

>    >         static time_point now() noexcept;

>    >         // Conversion functions, see below
>    >       };
>    >     }

>    > -1- The clock `file_clock` is an alias for a type meeting the `TrivialClock` requirements (29.3 [time.clock.req]), uses a signed arithmetic type for `file_clock::rep`, and is used to create the `time_point` system used for `file_time_type` (31.12 [filesystems]). Its epoch is unspecified. [Note: The type `file_clock` denotes may be in a different namespace than `std::chrono`, such as `std::filesystem`. — end note]

> 4. Change 29.7.6.2 [time.clock.file.members] as indicated:

>    >     static time_point now();

>    > > -1- Returns: A `file_clock::time_point` indicating the current time.

>    > > -2- The class `file_clock` shall type denoted by `file_clock` provides precisely one of the following two sets of static member functions: […]

[2018-07-30 Priority set to 1 after reflector discussion; wording updates based on several discussion contributions.]

Previous resolution [SUPERSEDED]:

> This wording is relative to N4762.

> 1. Change 29.2 [time.syn], header `<chrono>` synopsis, as indicated:

>    >     […]
>    >     // 29.7.6 [time.clock.file], classtype file_clock
>    >     classusing file_clock = see below;
>    >     […]

> 2. Change 29.7.6 [time.clock.file] as indicated:

>    > 23.17.7.5 Class Type `file_clock` [time.clock.file]

> 3. Change 29.7.6.1 [time.clock.file.overview], class `file_clock` synopsis, as indicated:

>    >     namespace std::chrono {
>    >       using file_clock = see below;
>    >       class file_clock {
>    >       public:
>    >         using rep = a signed arithmetic type;
>    >         using period = ratio<unspecified, unspecified>;
>    >         using duration = chrono::duration<rep, period>;
>    >         using time_point = chrono::time_point<file_clock>;
>    >         static constexpr bool is_steady = unspecified;

>    >         static time_point now() noexcept;

>    >         // Conversion functions, see below
>    >       };
>    >     }

>    > -1- The clock `file_clock` is an alias for a type meeting the `TrivialClock` requirements (29.3 [time.clock.req]), which uses a signed arithmetic type for `file_clock::rep`. `file_clock` is used to create the `time_point` system used for `file_time_type` (31.12 [filesystems]). Its epoch is unspecified, and `noexcept(file_clock::now())` is `true`. [Note: The type `file_clock` denotes may be in a different namespace than `std::chrono`, such as `std::filesystem`. — end note]

> 4. Change 29.7.6.2 [time.clock.file.members] as indicated:

>    >     static time_point now();

>    > > -1- Returns: A `file_clock::time_point` indicating the current time.

>    > > -2- The class `file_clock` shall type denoted by `file_clock` provides precisely one of the following two sets of static member functions: […]

[2018-08-23 Batavia Issues processing: Minor wording changes, and status to "Tentatively Ready".]

[2018-11, Adopted in San Diego]

Proposed resolution:

This wording is relative to N4762.

1. Change 29.2 [time.syn], header `<chrono>` synopsis, as indicated:

   >     […]
   >     // 29.7.6 [time.clock.file], classtype file_clock
   >     classusing file_clock = see below;
   >     […]

2. Change 29.7.6 [time.clock.file] as indicated:

   > 23.17.7.5 Class Type `file_clock` [time.clock.file]

3. Change 29.7.6.1 [time.clock.file.overview], class `file_clock` synopsis, as indicated:

   >     namespace std::chrono {
   >       using file_clock = see below;
   >       class file_clock {
   >       public:
   >         using rep = a signed arithmetic type;
   >         using period = ratio<unspecified, unspecified>;
   >         using duration = chrono::duration<rep, period>;
   >         using time_point = chrono::time_point<file_clock>;
   >         static constexpr bool is_steady = unspecified;

   >         static time_point now() noexcept;

   >         // Conversion functions, see below
   >       };
   >     }

   > -1- The clock `file_clock` is an alias for a type meeting the `Cpp17TrivialClock` requirements (29.3 [time.clock.req]), and using a signed arithmetic type for `file_clock::rep`. `file_clock` is used to create the `time_point` system used for `file_time_type` (31.12 [filesystems]). Its epoch is unspecified, and `noexcept(file_clock::now())` is `true`. [Note: The type that `file_clock` denotes may be in a different namespace than `std::chrono`, such as `std::filesystem`. — end note]

4. Change 29.7.6.2 [time.clock.file.members] as indicated:

   >     static time_point now();

   > > -1- Returns: A `file_clock::time_point` indicating the current time.

   > > -2- The type `file_clock` shall type denoted by `file_clock` provides precisely one of the following two sets of static member functions: […]