Clang的libc ++:在std :: chrono :: duration的定义中使用long long

Gre*_*ape 0 c++ clang c++11 libc++

在32位平台上的libc ++中,int64_t被定义为别名long long.在64位平台上:long.

另一方面,在std::chrono::duration别名的定义中,您可以在这里 long long不经意地使用:

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;
Run Code Online (Sandbox Code Playgroud)

因此,例如,当我需要严格8字节长的类型时,我会期望

  foo(uint64_t);
  foo(int64_t);
Run Code Online (Sandbox Code Playgroud)

是一个相当便携的解决方案.但是在libc ++的情况下,chrono它不是真的.除了编写类似于你自己的逻辑之外,没有可移植的方法<cstdint>.即,定义的两个额外的定义,foo称取long longunsigned long long.

或者另一个例子:

  foo(int8_t);
  foo(int16_t);
  foo(int32_t);
  foo(int64_t);
Run Code Online (Sandbox Code Playgroud)

foo(duration.count())在这种情况下,呼叫将是模棱两可的.

那么什么用的点long long是不大于long但它的等级大于long所以它不能被隐式转换?

这是开发商的疏忽libc++吗?

我提出这个的原因是因为mongodb的驱动程序无法在x64 FreeBSD安装上编译.原因看起来很傻.例如,GCC使用int64_t中的定义std::chrono::duration,因此它编译,如所预期.

Seb*_*edl 5

该标准仅要求比率为1的" secondstypedef duration"和"至少35位的有符号整数类型".所以libc ++的实现是正确的.

虽然int64_t在特定情况下使用会降低可移植性,但这只能带你到目前为止.MSVC也使用long long,而不是int64_t.(虽然在那种情况下,它们是相同的类型.)标准不保证int64_t持续时间,因此即使再有一个实现使用它,依赖它也是不可移植的.

这里的问题不是libc ++的实现做得不好.问题是,C++的整数类型有些扭曲,尽管该intNN_t类型是方便,但不完全免费,你从寂寂的基本类型.特别是,尝试foo使用那些typedef 进行完整的重载设置是错误的; 你需要准确地找到基础类型,因为你遇到的问题:重载集可能会或可能不会覆盖long long,你最终会遇到这种类型.它发生在libc ++的durationtypedef而不是其他一些情况只是巧合.

是的,这是一个糟糕的情况,但这个特殊问题只是一个较大问题的一个小症状.