我怎么在C中要求"至少"一个int的大小

der*_*ery 57 c c++ optimization

情况:

我有一个用C编写的应用程序,它是资源密集型的,并且设计为可移植的.我想允许编译器为架构选择最快的int大小,前提是它至少为32位.

是否可以选择"至少"32位的大小,或者编译器会自动优化这些类型的东西吗?

Dre*_*wen 92

标准头stdint.h提供的种类int_leastN_tuint_leastN_t,其中N为8,16,32,和64(以及可能的其他,但这些不是必需的).这些是C99的标准配置.

它还提供了"快"的替代品,又名int_fastN_tuint_fastN_t,用相同的值N.

所以,在你的情况下,你可以使用int_least32_tint_fast32_t.

  • `int_fast32_t`是OP需要的东西.`int_least32_t`不是32+位的最快整数类型,只是最小的. (34认同)
  • 除了`int_fast32_t`在x86_64之类的重要arch上被错误定义,其中它实际上是一个**慢得多的**类型(64位而不是32位):对于`+`/`-` /`*`两者都是相同的速度,但是对于`/`它要慢得多,当然加载/存储速度较慢,因为你使用两倍的缓存行和两倍的内存带宽.所以我真的对使用它犹豫不决.我不知道**任何具有32位int的**arch,它不是使用"至少32位"整数的最快类型. (3认同)

sup*_*cat 20

正如其他人指出,该标准包括文件定义int_fast32_t,int_least32_t,uint_fast32_t,uint_least32_t 这应该有可能表现为你想要的,但这样的类型需要格外小心使用.由于整数提升规则,C代码无法避免使用类型intunsigned int.此外,整数文字可能并不总是所期望的类型.a int_fast32_T和文字之间的比较,0xABCD1234或者12345u,例如,可以作为有符号或无符号执行,这取决于是否int是16位,32位或64位.同样,如果n是32位或更大,则n &= ~0x8000;16位机器上的含义与较大的机器上的含义不同.

C标准从未特别设计用于编写关注整数大小的代码,但仍然可以在具有不同大小的硬件上兼容.类似的类型int_fast32_t可以很容易地编写看起来应该是可移植的代码,但可能会鼓励对隐藏在语言中的所有讨厌的小陷阱感到自满.


Man*_*726 10

这个问题也被标记为C++,所以这里是像我这样的模板元编程爱好者的解决方案.

要求

  • 类型列表类型,list在此处命名.
  • 类似Haskell的filter元函数.
  • head元函数来获得一个类型串的第一个元素.

代码

此解决方案可自动执行已接受的解决方案(这只是" stdint.h为您选择最适合您的解决方案").那个工作可以由编译器完成,不是吗?

首先列出在<cstdint>以下位置声明的所有特定于平台的快速整数

using integer_types = list<std::int_fast8_t,std::int_fast16_t,
                           std::int_fast32_t,std::int_fast64_t>;
Run Code Online (Sandbox Code Playgroud)

请注意,列表按增加的整数大小排序.
现在定义过滤谓词.在我们的例子中,大小应该小于用户指定的大小(将其命名SIZE):

template<typename T>
using f = std::integral_constant<bool,sizeof(T)*CHAR_BITS <= SIZE>;
Run Code Online (Sandbox Code Playgroud)

然后过滤整数类型列表并获取结果的第一个元素:

using best_integer_t = head<filter<f,integer_types>>;
Run Code Online (Sandbox Code Playgroud)

总结解决方案

template<std::size_t SIZE>
struct fastest_integer_impl
{
    //Guard for the case the user specified less than one byte size:
    static constexpr const std::size_t size = SIZE >= CHAR_BITS ? size : CHAR_BITS;

    using integer_types = list<std::int_fast8_t,std::int_fast16_t,
                               std::int_fast32_t,std::int_fast64_t>;

    template<typename T>
    using f = std::integral_constant<bool,sizeof(T)*CHAR_BITS <= size>;

    using type = head<filter<f,integer_types>>;
};

template<std::size_t SIZE>
using fastest_integer = typename fastest_integer_impl<SIZE>::type;
Run Code Online (Sandbox Code Playgroud)

  • `fast_integer <4>`不会与`std :: int_fast32_t`相同吗?这比直接使用`std :: int_fast32_t`更好吗? (8认同)