使用gcc使用常量及其相关修饰符
Using constants and their associated modifiers using gcc
我不知道该怎么称呼这些标志,但我指的是:
#define TEST_DEF 50000U //<- the "U" here
当你不熟悉用来描述你的问题的术语时,谷歌搜索是徒劳的。
我要做的是使用这些常量定义,并确保值只有一定的长度,即8或16位。
我怎么做,它被称为什么?
对于整数,标准(ISO/IEC 9899:2011 -又名C2011或C11)定义这些后缀的部分为:
§6.4.4.1整型常量
其中定义了整数后缀:
integer-suffix :
,,, unsigned-suffix long-suffix <子>选择子>
,,, unsigned-suffix long-long-suffix
,,, long-suffix unsigned-suffix <子>选择子>
,,, long-long-suffix unsigned-suffix <子>选择子>unsigned-suffix:
,,,,u U
long-suffix:,,,,
l L
long-long-suffix:
,,,,ll LL
对应的浮点数后缀为f
、F
、l
和L
(float
和long double
)。
请注意,使用l
是不合理的,因为它太容易与1
混淆,所以限定符通常用大写字母书写。
如果您想要创建给定大小的整数字面值,那么<stdint.h>
(在C99中添加)将实现此功能的标准化。
头(有条件地)定义了固定大小的类型,如int8_t
和uint16_t
。它还(无条件地)提供最小大小的类型,如int_least8_t
和uint_least16_t
。如果它不能提供确切的类型(可能因为字长是36位,所以可以处理9、18和36的大小),它仍然可以提供最少的类型。
它还提供了INT8_C
这样的宏来确保参数是int_least8_t
的值。
因此,您可以使用:
#include <stdint.h>
#define TEST_DEF UINT16_C(50000)
,您可以保证该值至少为16位无符号整数,并正确格式化/限定。
§7.20.4整型常量的宏
下面的类函数宏展开为适合初始化的整型常量具有与<stdint.h>
中定义的类型对应的整数类型的对象。每一个宏名对应于7.20.1.2或7.20.1.5中类似的类型名。 这些宏的任何实例中的实参都必须是一个无后缀的整型常量(如定义于6.4.4.1),其值不超过对应类型的限制。 这些宏的每次调用都应该展开为一个整型常量表达式适合在#if预处理指令中使用。表述的类型应当有与根据转换的相应类型的表达式相同的类型整数提升。表达式的值应为实参的值。7.20.4.1最小宽度整型常量的宏
宏INTN_C(value)
应该展开为一个整型常量表达式对应int_leastN_t
类型。扩展宏UINTN_C(value)
转换为与类型uint_leastN_t
对应的整型常量表达式。为例如,如果uint_least64_t
是类型unsigned long long int
的名称,则UINT64_C(0x123)
可能展开为整型常数0x123ULL
。
C中有5个整数字尾: u
、l
、ul
、ll
、ull
。不像C中几乎所有其他东西,它们不区分大小写;另外,ul
和ull
也可以分别写成lu
和llu
(但不能写成lul
)。
它们控制常量的类型。它们的工作方式大致如下:
literal │ type
────────┼───────────────────────
500 │ int
500u │ unsigned int
500l │ long int
500ul │ unsigned long int
500ll │ long long int
500ull │ unsigned long long int
这只是一个近似值,因为如果常量对于指定的类型来说太大,它将被"提升"为更大的类型。它的规则非常复杂,我就不去描述了。"提升"十六进制和八进制文字的规则与"提升"十进制文字的规则略有不同,它们在C99和C90中也略有不同,在c++中也有所不同。
由于提升效果,不可能使用这些后缀将常量限制为任何大小。如果您在int
和long
都是32位宽的系统上编写281474976710656
,则常量将被指定为long long
类型,即使您没有这样做。此外,没有后缀强制常量具有short
或char
类型。你可以用<stdint.h>
中的[U]INT{8,16,32,64,MAX}_C
宏来指示你的意图,但这些宏也不施加任何上限,而且在我现在可以方便地得到的所有系统上(OSX, Linux), *INT8_C
和*INT16_C
实际上产生类型为(unsigned) int
的值。
您的编译器可能,但不是必需的,警告如果你写((uint8_t) 512)
或类似(其中512是一个编译时常数值超出类型的范围。在C11中,您可以使用static_assert
(来自<assert.h>
)来强制执行该问题,但编写起来可能有点繁琐。
这是一个无符号文字(U是后缀)。参见:http://en.cppreference.com/w/cpp/language/integer_literal
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- constexpr 函数的常量引用参数:gcc/msvc vs clang/icc
- 使用函数参数作为常量表达式的一部分 - gcc vs clang
- 为什么 GCC 拒绝复制赋值操作中的常量引用
- GCC 模板推导消除了常量错误
- 避免或警告在 GCC 中从常量字符* 隐式转换为布尔值
- 将函数声明为 GCC 纯函数或常量函数的效果(当它不是时)
- gcc 是否将非常量表达式函数的内置视为常量表达式
- GCC可以优化具有编译时常量变量的类的方法吗
- GCC C++11 对用户定义的常量和模板参数包的限制
- 二进制表达式中的 GCC 常量临时
- 非常量引用类型的无效初始化中出错.在Linux操作系统中使用c++代码.GCC编译器
- 有没有办法不警告 gcc 中开关缺少"COUNT"枚举常量?
- GCC 3.3 具有类似于 GCC 3.4 的静态常量变量
- GCC 4.7.1 泛量常量表达式问题与重载
- 在类嵌套静态常量成员变量初始化 Clang vs GCC 哪个编译器是正确的
- GCC 错误,同时对常量无符号长字节使用代码块
- Linux gcc和Windows Visual Studio处理静态常量的区别
- GCC 4.4.3常量表达式错误的偏移.我应该如何解决这个问题
- 如何使GCC的长整型常量警告静音