【问题标题】:Using constants and their associated modifiers using gcc使用 gcc 使用常量及其相关修饰符
【发布时间】:2014-05-25 18:11:06
【问题描述】:

我不知道如何称呼这些标志,但我指的是:

#define TEST_DEF 50000U //<- the "U" here

当您不熟悉用于描述您的问题的术语时,Google 搜索是徒劳的。

我要做的是使用这些常量定义并确保该值仅具有一定的长度,即 8 位或 16 位。

我该怎么做?它被称为什么?

【问题讨论】:

标签: c++ c gcc constants


【解决方案1】:

对于整数,定义这些后缀的标准部分(ISO/IEC 9899:2011 — 也称为 C2011 或 C11)是:

§6.4.4.1 整数常量

定义整数后缀的地方:

整数后缀
无符号后缀长后缀opt
unsigned-suffix long-long-suffix
长后缀无符号后缀opt
long-long-suffix unsigned-suffixopt

无符号后缀:
之一 u U

长后缀:
之一 l L

long-long-suffix:
之一 ll LL

浮点数对应的后缀是fFlL(对于floatlong double)。

请注意,使用l 是不恰当的,因为它很容易与1 混淆,因此限定词通常用大写字母书写。

如果您想要创建具有给定大小的整数文字,那么执行此操作的工具由 &lt;stdint.h&gt; 标准化(在 C99 中添加)。

标头(有条件地)定义固定大小的类型,例如int8_tuint16_t。它还(无条件地)提供最小大小的类型,例如int_least8_tuint_least16_t。如果它不能提供精确的类型(可能是因为字长是 36 位,所以处理了 9、18 和 36 的大小),它仍然可以提供最少的类型。

它还提供了诸如INT8_C 之类的宏来确保参数是int_least8_t 值。

因此,您可以使用:

#include <stdint.h>

#define TEST_DEF UINT16_C(50000)

并且您可以保证该值至少是 16 位无符号整数,并且格式/限定正确。

§7.20.4 用于整数常量的宏

¶1 以下类似函数的宏扩展为适合初始化的整数常量 具有与&lt;stdint.h&gt; 中定义的类型相对应的整数类型的对象。每个 宏名称对应于 7.20.1.2 或 7.20.1.5 中的类似类型名称。

¶2 这些宏的任何实例中的参数都应是无后缀的整数常量(如 在 6.4.4.1 中定义),其值不超过相应类型的限制。

¶3 这些宏之一的每次调用都应扩展为整数常量表达式 适用于#if 预处理指令。表达式的类型应具有 与根据以下转换的相应类型的表达式相同的类型 整数促销。表达式的值应该是参数的值。

7.20.4.1 最小宽度整数常量的宏

¶1 宏 INTN_C(value) 应扩展为整数常量表达式 对应于类型int_leastN_t。宏 UINTN_C(value) 应展开 对应于类型uint_leastN_t 的整数常量表达式。为了 例如,如果uint_least64_tunsigned long long int 类型的名称, 那么UINT64_C(0x123) 可能会扩展为整数常量0x123ULL

【讨论】:

    【解决方案2】:

    C 中有五个整数文字后缀ululllull。与 C 中的几乎所有其他内容不同,它们不区分大小写;另外,ulull 可以分别写为 lullu(但是,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++ 中也有所不同。

    由于提升效果,无法使用这些后缀将常量限制为任何大小。如果您在intlong 都是32 位宽的系统上编写281474976710656,即使您没有说要这样做,常量也会被赋予long long 类型。此外,没有后缀可以强制常量具有shortchar 类型。您可以使用来自&lt;stdint.h&gt;[U]INT{8,16,32,64,MAX}_C 宏来表明您的意图,但这些宏也没有施加任何上限,并且在我现在可以方便地使用的所有系统(OSX、Linux)上, *INT8_C*INT16_C 实际上会产生 (unsigned) int 类型的值。

    您的编译器可能在您编写 ((uint8_t) 512) 或类似内容时发出警告(其中 512 是超出类型范围的编译时常量值。在 C11 中,您可以使用static_assert(来自&lt;assert.h&gt;)来强制解决这个问题,但写起来可能有点乏味。

    【讨论】:

      【解决方案3】:

      这是一个无符号文字(U 是后缀)。见:http://en.cppreference.com/w/cpp/language/integer_literal

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-29
        • 1970-01-01
        • 1970-01-01
        • 2022-06-16
        • 1970-01-01
        • 1970-01-01
        • 2015-12-10
        相关资源
        最近更新 更多