mercredi 30 mars 2016

Clang's libc++: using long long in the definition of std::chrono::duration

In libc++ on 32-bit platforms, int64_t is defined as alias of long long. On 64-bit platforms: long.

On the other hand in definition of std::chrono::duration aliases, that you can find here long long is carelessly used:

typedef duration<long long,         nano> nanoseconds;
typedef duration<long long,        micro> microseconds;
typedef duration<long long,        milli> milliseconds;
typedef duration<long long              > seconds;
typedef duration<     long, ratio<  60> > minutes;
typedef duration<     long, ratio<3600> > hours;

So for example, when I require type that is strictly 8 bytes long, I would expect

  foo(uint64_t);
  foo(int64_t);

to be a fairly portable solution. But in case of libc++'s chrono it is not true. There is no portable way except to write your own logic similar to <cstdint>. Ie, defining two additional definitions of foo that take long long and unsigned long long.

Or another example:

  foo(int8_t);
  foo(int16_t);
  foo(int32_t);
  foo(int64_t);

Calling foo(duration.count()) would be ambiguous in this case.

So what the point of using long long that is not larger than long but it's rank is greater than long so it cannot be implicitly cast?

Is this an oversight by developers of libc++?

The reason I brought this up is because drivers of mongodb won't compile on x64 FreeBSD installation. And the reason looks rather silly. For example, gcc used int64_t in the definitions of std::chrono::duration and so it compiles, as expected.

Aucun commentaire:

Enregistrer un commentaire