【问题标题】:Why I cannot qualify a aliased type with "unsigned"?为什么我不能用“无符号”来限定别名类型?
【发布时间】:2016-03-22 14:36:46
【问题描述】:

我正在将我的代码从 Windows 迁移到 Linux。 Linux上没有名为“__int64”的类型,所以我尝试用别名自己定义它。我的代码如下:

#include <cstdint>

#if !defined(__int64)
typedef int64_t __int64;
#endif

int main(int argc, char** argv)
{
    unsigned __int64 ii64 = 0; // Error
    return 0;
};

当我编译它时,我得到了以下错误:

main.cpp: 在函数'int main(int, char**)': main.cpp:10:20: 错误: 'ii64' 之前的预期初始化程序

我知道可以将“unsigned __int64”替换成“uint64_t”或者定义一个新的类型,但是为什么前面的代码不能编译?

【问题讨论】:

  • unsigned 这个词不是限定词。 (unsigned int 类型不是添加了unsignedint 类型,它是一个完全独立的类型。)您总是可以使用宏来代替。
  • 您认为 typedef 是一个具有关联替换规则的宏,但不是这样。
  • 是的,你是对的,但“定义”也不起作用。
  • 如果它奏效了,我决定我真的很喜欢我的LargeInteger 课程,而是写了typedef int64_t LargeInteger,你希望发生什么?
  • 此外,int64_t 无论如何都不是unsigned 可以“限定”的类型

标签: c++ linux windows


【解决方案1】:

参见标准 7.1.6/2:

作为一般规则,最多允许一个类型说明符在 声明的完整 decl-specifier-seq 或在 类型说明符序列或尾随类型说明符序列。唯一的例外 这条规则如下:

有符号或无符号可以与 char、long、short 或 int 组合。

请注意,这并不意味着 unsigned 可以与最终可能是其中一种类型的 typedef 组合,它只能直接与其他类型组合。

此外,请记住,__int64 是为编译器保留的,因此您自己定义它在技术上是非法的。你最好使用标准的int64_tuint64_t 类型。

【讨论】:

  • 谢谢你这么具体的回答!
【解决方案2】:

因为 typedef 不是宏。它是一种新类型!而且你不能构造这样的类型。

当您说unsigned int 时,它与const int 的语义不同。 const 是所谓的类型限定符。这意味着,它没有指定新类型,而是向现有类型添加了一些属性。但是,unsigned 不是类型限定符。 unsigned int 是它自己的类型。

【讨论】:

  • 这是一个有趣的问题。除了宏观性之外,我想不出任何理由添加 unsigned 属性是无效的,除非编译器已经认为该类型已完全定义并禁止任何进一步的属性操作。对一些标准文档的简要阅读并没有对这个主题有任何启示,无论是赞成还是反对。
  • 啊。看起来@MarkB 已经成功了。
  • 我了解typedef 定义了一种新类型。但是宏 define 也不起作用。
【解决方案3】:

首先,“unsigned int”是一种类型,但“unsigned int64_t”不是。

【讨论】:

  • typedef uint64_t __int64; 这不是非常令人困惑和误导吗?这不会通过我的代码审查。
  • 同意。删除了丑陋的代码。感谢您的评论。
【解决方案4】:

除此之外,那是因为没有类型unsiged int64_t。由于同样的原因,宏不起作用。但是如果你#define __int64 int,这将起作用,因为有一个类型unsigned int

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 2015-01-08
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    相关资源
    最近更新 更多