【问题标题】:C++ integer constant's typeC++ 整数常量的类型
【发布时间】:2015-05-26 12:41:23
【问题描述】:

根据 MSDN (Integer Types - VC2008):

不带后缀的十进制常量的类型是 int、long int 或 unsigned long int。这三种类型中的第一种 常量的值可以表示为分配给 常数。

Visual C++ 2008上运行以下代码:

void verify_type(int a){printf("int [%i/%#x]\n", a, a);}
void verify_type(unsigned int a){printf("uint [%u/%#x]\n", a, a);}
void verify_type(long a){printf("long [%li/%#lx]\n", a, a);}
void verify_type(unsigned long a){printf("ulong [%lu/%#lx]\n", a, a);}
void verify_type(long long a){printf("long long [%lli/%#llx]\n", a, a);}
void verify_type(unsigned long long a){printf("unsigned long long [%llu/%#llx]\n", a, a);}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("sizeof(int) %i\n", sizeof(int));
    printf("sizeof(long) %i\n", sizeof(long));
    printf("sizeof(long long) %i\n\n", sizeof(long long));

    verify_type(-2147483647);
    verify_type(-2147483648);

    getchar();
    return 0;
}

我明白了:

sizeof(int) 4
sizeof(long) 4
sizeof(long long) 8

int [-2147483647/0x80000001]
ulong [2147483648/0x80000000]  <------ Why ulong?

我希望 const -2147483648 () 是 int。为什么我得到的是 ulong,而不是 int?

我已经编程了很长时间,直到今天我还没有注意到 + 或 - 不是整数常量的一部分。这一提示说明了一切。

      integer-constant:
              decimal-constant integer-suffix<opt>
              octal-constant integer-suffix<opt>
              hexadecimal-constant integer-suffix<opt>

      decimal-constant:
              nonzero-digit
              decimal-constant digit

      octal-constant:
              0
              octal-constant octal-digit

      hexadecimal-constant:
              0x  hexadecimal-digit
              0X  hexadecimal-digit
              hexadecimal-constant hexadecimal-digit

      nonzero-digit: one of
              1  2  3  4  5  6  7  8  9

      octal-digit: one of
              0  1  2  3  4  5  6  7

      hexadecimal-digit: one of
              0  1  2  3  4  5  6  7  8  9
              a  b  c  d  e  f
              A  B  C  D  E  F

      integer-suffix:
              unsigned-suffix long-suffix<opt>
              long-suffix unsigned-suffix<opt>

      unsigned-suffix: one of
              u  U

      long-suffix: one of
              l  L

【问题讨论】:

  • 这个让我很烦。我在这里也有不同的结果:ideone.com/HyyI3r
  • 请注意,您的许多 printf 语句会导致未定义的行为。您不能将负值传递给 %x%lx
  • C 中没有函数重载,所以代码在 C 中无法编译。这是一些 C++ 的东西。
  • @Orace 您正在使用 C++11 来获得这些结果,但是 OP 使用的是 2008 编译器。在 C++11 之前,C++ 没有 long long,因此必须使用编译器扩展。编译器扩展应该被记录在案......
  • 当表示为 32 位时,值 2147483648 和 -2147483648 具有完全相同的值:0b10000000000000000000000000000000。编译器如何知道使用哪个?

标签: c++ types long-integer


【解决方案1】:

您正在将一元 - 运算符应用于整数文字 2147483648。整数文字 2^31 太大而无法放入 32 位 int。在现代 C++ 中,它应该被视为long long,所以你的结果令人惊讶。

我相信旧的 C 标准(在 long long 之前)允许解释对于 long 来说太大而无法具有类型 unsigned long 的文字,这与您所看到的一致。我看到您在帖子顶部引用的 MSDN 文档重复了这一点,所以这肯定是这里发生的事情。

【讨论】:

  • C++ 在 C++11 之前没有 long long。我确定 VS2008 没有 C++11。但是,MS 可能已经添加了自己的 int64 类型作为扩展,并设计了一些处理常量的方法。
  • OP 链接的文档标题为“C 常量”,因此它可能不适用;但是,这与他显示的输出一致。也许编译器使用 C++03 定义常量直到 4294967295,然后切换到long long。什么的。
  • @MattMcNabb:IIRC,MSVC 以理智的方式对待它。任何太大的文字都会导致 UB。 UB 的一种有效且合理的形式是具有__int64 类型的整数文字。
【解决方案2】:

首先,-2147483648 不是整数常量,因为- 是一元运算符,不是常量的一部分(至少在这种情况下)。 2147483648 是一个整数常量,-2147483648 是一个包含该常量的表达式。

因为2147483648 不能表示为intlong int,但可以表示为unsigned long int,所以它的类型为unsigned long int。将一元 - 运算符应用于 unsigned long int 的结果本身就是 unsigned long int

【讨论】:

    【解决方案3】:

    -2147483648 不是整数文字。它是应用于整数文字2147483648 的一元运算符-。该文字的值不适合signed intsigned long,因此它的类型为unsigned long- 运算符不会更改该类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-27
      • 1970-01-01
      • 2016-10-16
      相关资源
      最近更新 更多