Gcc扩展或宏,用于在编译时检查用于某些基本类型的位

时间:2014-11-28 04:03:56

标签: c++ c gcc clang

在编译时,有些人使用static_assert,我想检查一些简单类型的位大小,例如unsigned intchar,重要的是它将被授予根据我的用法在编译时发生。

我在gcc手册中找不到任何相关信息,我对clang提供的类似功能一无所知,任何人都知道如何检查a使用的位数输入?

请不要,我的重点是和编译时间。

3 个答案:

答案 0 :(得分:6)

  

请不要,我的重点是比特和编译时间。

保持开放的心态;-P

#include <cstdint>

static_assert(sizeof(X) * CHAR_BIT == 32, "type X must be 32 bits in size");

答案 1 :(得分:2)

1。如何在不使用CHAR_BIT

的情况下查找类型中的位数

如果类型是数字类型(例如intchar),则可以使用std::numeric_limits<T>::digits获取重要位的数量假设 T是二进制类型(即std::numeric_limits<T>::radix == 2)。这些是constexpr,因此可以在static_assert中使用。

实现可能无法使用某些数字类型中的所有存储位(char除外),在这种情况下,有效位数可能与位的物理大小无关。此外,符号位不计,因此您需要添加std::numeric_limits<T>::is_signed以获取非填充位的数量。

由于char类型不允许填充,charsigned charunsigned char必须具有完全相同的大小,std::numeric_limits<unsigned char>::digits必须是char中的位数,也称为必需的宏CHAR_BIT。因此,您可以交替使用这两个表达式,因此任何类型T的位大小(物理的,无意义的)都将是sizeof(T)*std::numeric_limits<unsigned char>::digits

我不相信编译器本身需要知道char的比特大小是什么(尽管大多数编译器可能都这样做)。它确实需要知道每个基本类型的sizeof(T)是什么。没有标准规定的方法来确定std::numeric_limits<unsigned char>::digits的值是什么,而不包括一些头文件。

2。为什么你不应该担心它。

在独立环境中,<numeric_limits>不是必需的,但<climits>仍然是,所以即使在独立环境中也可以依靠CHAR_BIT,而您只能依靠std::numeric_limits<unsigned char>::digits {1}}在托管环境中。

换句话说,编译器必须有某种方式提供#include <climits>的结果,因为即使在独立环境中(即没有标准库甚至是操作的环境),标准也需要该标头系统)。这就是你要找的“内置”;即使您没有在标准库实现中提供<climits>,即使您没有方便的标准库,编译器仍必须安排宏CHAR_BIT正确定义发生#include <climits>。它如何取决于编译器; <climits>不一定是实际文件。

注释

  1. 上述所有内容都不适用于C,但后来static_assert也不会这样,所以我假设将此问题标记为C是疏忽。正如@mafso在评论中指出的那样,C11确实有static_assert声明,但它只适用于C11风格的常量表达式,而不适用于C ++风格的常量表达式。 C ++常量表达式可以使用constexpr函数之类的东西,这些函数可能是内置函数。另一方面,C常量表达式只能涉及整数文字。它们仍然有用(对于非纯粹主义者),因为宏扩展首先发生,并且宏可以扩展为整数文字(甚至是涉及几个整数文字的表达式)。

答案 2 :(得分:1)

根据this document,gnu编译器将为您定义这些宏:

__CHAR_BIT__      // bits

__SIZEOF_INT__    // bytes
__SIZEOF_LONG__
__SIZEOF_LONG_LONG__
etc...

您只需乘以8即可从字节宏中定义自己的位宏。

编辑:因为你显然需要知道&#34;字大小&#34;并考虑指针与&#34; word&#34;的大小相同,然后使用:

__SIZEOF_POINTER__