【问题标题】:Is int x = 'fooo' a compiler extension?int x = 'fooo' 是编译器扩展吗?
【发布时间】:2010-10-16 12:07:23
【问题描述】:

我见过并使用过如下 C++ 代码:

int myFourcc = 'ABCD';

它可以在最新版本的 GCC 中使用,但不确定最近的版本。 这个功能在标准中吗? 它叫什么?

我在网上搜索它时遇到了麻烦...

编辑:

我也找到了这个信息,供未来的观察者参考:

来自gcc documentation

编译器每次为一个字符赋值一个多字符字符常量,将前一个值左移每个目标字符的位数,然后在截断到宽度的新字符的位模式中进行或运算的目标人物。最终的位模式被赋予 int 类型,因此是有符号的,无论单个字符是否有符号(与 GCC 3.1 和更早的版本略有不同)。如果常量中的字符多于目标 int 中的字符数,编译器会发出警告,并忽略多余的前导字符。

例如,对于具有 8 位字符的目标,'ab' 将被解释为 (int) ((unsigned char) 'a' * 256 + (unsigned char) 'b')', and '\234a' as (int) ((unsigned char) '\234' * 256 + (unsigned char) 'a')'。

【问题讨论】:

标签: c++ c gcc


【解决方案1】:

参见 C99 标准第 6.4.4.4 节第 10 段:

整数字符常量的类型为int。整数字符常量的值 包含映射到单字节执行字符的单个字符是 被解释为整数的映射字符表示的数值。 包含多个字符的整数字符常量的值(例如, 'ab'),或包含不映射到单字节的字符或转义序列 执行字符,是实现定义的。如果一个整数字符常量包含 单个字符或转义序列,其值是当对象具有 类型char,其值为单个字符或转义序列的值,转换为 输入int

回想一下,实现定义意味着实现(在本例中为 C 编译器)可以做任何想做的事情,但它必须记录在案

大多数编译器会将其转换为一个整数常量,对应于各个字符对应的八位字节的串联,但字节序可以是小端或大端,具体取决于目标体系结构的字节序。

因此,可移植代码不应使用多字符常量,而应使用纯整数常量。使用 0x61626364 或 0x64636261 代替 'abcd',这可能是任何一种字节序,它们具有已知的字节序(分别为大和小)。

【讨论】:

    【解决方案2】:

    "请注意,根据 C 标准,字符常量的长度没有限制,但是包含多个字符的字符常量的值是实现定义的。最新版本的 GCC 提供了对多字节的支持字符常量,并且在这种情况下会生成警告 multiple-character character constantwarning: character constant too long for its type,而不是错误。"

    【讨论】:

      【解决方案3】:

      C++ 标准草案说:

      字符文字是一个或多个字符包含在单个 引号,如 'x'

      包含多个 c-char 的普通字符文字是多字符文字。一个多字符 演员字面量具有 int 类型和实现定义的值

      【讨论】:

        【解决方案4】:

        是的,它是标准的,但由实现定义。

        在实际经验中,它表示通过连接字节“A”、“B”、“C”和“D”得到的 32 位整数。

        【讨论】:

        • 我猜由于字节序问题等原因,该标准未定义。
        • 它不是未定义的,它是实现定义的——细微的差别
        • 它是实现定义的,而不是未定义的。在实践中,我使用的所有编译器都至少接受最多 4 个字节,结果是这些字节的串联。
        【解决方案5】:

        如果有人感兴趣,给出的具体示例是数据存储格式的 ID。
        能够获得人类可读的常量值非常有用,例如“XVID”,而不仅仅是 1234。 当您组成任意整数键时,值得考虑一下。

        【讨论】:

        • 旧 Macintosh(大约 1990 年代)上的文件类型就是这样。令人讨厌的是,指定 0x3F3F3F3F 的逻辑方式不起作用。指定只有在某些指令明确要求时才应处理三元组会有任何问题吗?
        猜你喜欢
        • 2011-06-21
        • 1970-01-01
        • 2019-08-31
        • 2016-09-17
        • 1970-01-01
        • 2015-12-19
        • 1970-01-01
        • 2014-01-09
        • 1970-01-01
        相关资源
        最近更新 更多