为什么sizeof(unsigned double)等于4?


71

我的一个同事问是否有未签名的double,但我说没有,但我仍然检查了一下,并且可以在Microsoft Visual C ++ 2010中进行编译:

unsigned double a;
double b;
printf("size_a=%d size_b=%d", (int) sizeof(a), (int) sizeof(b));

它输出size_a=4 size_b=8。也就是说,的四个字节unsigned double,的八个字节double


3
MSVC中可能有无符号的double,但是在标准C ++中没有这样的东西。实际上,MSVC会警告您有关此构造的信息。您的团队应启用警告,并密切注意它们。
n。代词

10
一个1级警告发出这一点,如果你有警告关掉你可能会得到你应得的!;-)通常至少3级是明智的,/ Wx也是如此。
克利福德,

11
警告级别4应该是默认值。在我工作的任何新地方,我尝试做的第一件事是使其强制性并将警告作为错误启用。编写带有警告的代码没有任何借口。:)

3
已经有答案了。您可能也喜欢两个阅读这两个。为什么C没有未签名的浮点数?为什么没有无符号的浮点类型?
Grijesh Chauhan

6
需要编译器才能发出诊断unsigned double。警告满足语言标准的诊断要求。不过,我认为这是一个编译器错误;没有充分的理由允许该代码成功编译。
基思·汤普森

Answers:


141

unsigned double是无效的。在MSVC中也是如此。在启用警告的情况下在MSCV 2010中编译以上代码时,您将获得:

warning C4076: 'unsigned' : can not be used with type 'double'

编译器实际上会忽略 double之后unsigneda实际上使您成为一个unsigned int

如果您尝试以下操作:

unsigned double a = 1.0;

您实际上收到两个警告:

warning C4076: 'unsigned' : can not be used with type 'double'
warning C4244: 'initializing' : conversion from 'double' to 'unsigned int', possible loss of data

有趣的是,VS2010在MSDN中没有C4076警告。仅在VS2005和VS2008中存在。


23
@PeteBecker不傻。通常会针对过去导致错误的问题发出警告。高中或以上的人不会对+ vs *优先权感到困惑;&& vs ||不能这么说。在我学习形式逻辑之前很久我就在编程(并对它们的优先级感到困惑)。
塞巴斯蒂安·雷德尔

14
@PeteBecker欢迎您禁用该警告,并告诉编程团队中的人们他们必须认真学习优先顺序。假设您无论在哪里工作都具有这种能力,那实际上就是您的选择。但是实际情况是,这一直是错误的来源,并且将继续是错误的来源,因此请不要将警告称为愚蠢的方式。
塞巴斯蒂安·雷德尔

9
@PeteBecker括号实际上会引起任何问题吗?它们在编译时是否仍未得到优化?如果它们不会引起问题,甚至不会对编译后的代码产生任何影响,那么它们所做的只是使人们更容易阅读代码,这是一件好事,不是吗?
Matt Fellows

16
@PeteBecker-我理解并同意您关于警告不是真正警告的观点。但是说“专业程序员”不带括号就更容易理解代码行是完全错误的。我从事专业程序员已有15年,知道优先规则。您的示例中的两行代码对我来说都一样清楚。加上括号进行说明(就像数学家一样)不会使我更难以阅读和理解。
CramerTV

10
@PeteBecker-return(a || b && c <d + e * f + ++ g-h--); 这里也不需要parens。这真的和非最小版本一样清晰吗?还原荒谬。不能与思想家争论-我出去了。
CramerTV

26

如果将警告级别设置为更高(在我的测试中为/ W3),则会收到适当的警告:

警告C4076:“无符号”:不能与类型“ double”一起使用

如果然后使用调试器检查变量,则所有内容将变得清楚:

在此处输入图片说明

您可以看到变量实际上是 unsigned int


24

在声明说明符序列中unsigned与组合double无效的C ++。这必须是某种MSVC扩展(或错误)。

作为一般规则,最多一个类型说明符被允许在完全DECL说明符-SEQ声明的或在一个类型说明符序列尾随类型说明符-SEQ。该规则的唯一例外如下:

  • const 可以与除自身以外的任何类型说明符结合使用。
  • volatile 可以与除自身以外的任何类型说明符结合使用。
  • signedunsigned可以结合charlongshort,或int
  • shortlong可以与结合使用int
  • long可以结合使用double
  • long可以结合使用long

5
+1我什至不知道有些疯子@ MS甚至考虑过将浮点数设为无符号。我敢肯定背后有一个原因,我只是认为这不是一个好方法
WhozCraig 2013年

我希望long long在第三个要点中成为列表的一部分。
juanchopanza

1
@juanchopanza我认为这是带符号的/不带符号的组合long。然后long可以与另一个结合long
约瑟夫·曼斯菲尔德

没有扩展或任何其他疯狂的MS的东西。
OrangeDog

@sftrabbit:那么长的时间可以再与另一个长的时间结合吗?这些多头可以变成多久?
Konerak

4

在可能的情况下,未签名和已签名可充当MSVC中的类型限定符(未签名的char,signed short等)。如果无法做到这一点,例如无符号布尔或带符号双精度,则不会创建请求的类型。并且该类型仅被视为无符号[int]和带符号[int]。


8
这是合法的C ++。C ++编译器必须对发布的代码发出诊断。(坦率地说,如果这是一个扩展,而不是一个错误,那是一个愚蠢的错误。)
James Kanze

1
这可能是一个警告,因为必须从大型的现有代码库(很可能在C语言)中抓取头文件。如果我正在编写C ++编译器,则在读取不包含任何C ++构造的.h文件时,会产生很多在C中合法的事情。
约书亚

@Joshua:unsigned double在C和C ++中均无效。
基思·汤普森

是的,但它在旧C中编译为“无符号”。
2013年

2

这是VS2010中的错误。VS2012对该代码行给出以下错误。

error CS1002: ; expected

它期待一个';' 在关键字“ double”之前。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.