72

A colleague of mine asked if there is unsigned double, and I said there isn't, but I still checked it, and this compiles in Microsoft Visual C++ 2010:

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

It outputs size_a=4 size_b=8. That is, four bytes for unsigned double, and eight bytes for double.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sashoalm
  • 75,001
  • 122
  • 434
  • 781
  • 3
    There may be unsigned double in MSVC, but there is no such thing in standard C++. In fact MSVC warns you about this construct. Your team should enable warnings, and watch them closely. – n. m. could be an AI Feb 20 '13 at 10:26
  • Note that `unsigned double` isn't standard C++. – juanchopanza Feb 20 '13 at 10:26
  • 10
    A [level 1 warning](http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k%28C4076%29;k%28VS.OUTPUT%29;k%28DevLang-%22C%2B%2B%22%29&rd=true) is issued for this, if you have warnings switched off you probably get what you deserve! ;-) Generally at least level 3 is wise and /Wx too. – Clifford Feb 20 '13 at 10:53
  • 11
    Warning level 4 should be the default. The first thing I try to do in any new place I work is make it mandatory and enable warnings as errors. There is no excuse for writing code with warnings in it. :) –  Feb 20 '13 at 12:04
  • Uh. `unsigned` ...what? `_double_`?! – alecov Feb 20 '13 at 12:12
  • Is this actually illegal according to the C++ spec as several commenters are implying or just undefined, and if so where in the spec? Do other compilers emit an error instead of taking a guess at what the coder meant and issue warnings as well? – Dan Is Fiddling By Firelight Feb 20 '13 at 15:20
  • 3
    Already got answers. You may also like two read this two. [**Why doesn't C have unsigned floats?**](http://stackoverflow.com/questions/512022/why-doesnt-c-have-unsigned-floats) and [**Why no unsigned floating point types?**](http://stackoverflow.com/questions/3589663/why-no-unsigned-floating-point-types) – Grijesh Chauhan Feb 20 '13 at 15:27
  • 6
    A compiler is required to issue a diagnostic for `unsigned double`. A warning satisfies the language standard's requirement for a diagnostic. Nevertheless, I consider this to be a commpiler bug; there is no good reason to permit that code to compile successfully. – Keith Thompson Feb 20 '13 at 17:11

5 Answers5

141

unsigned double is invalid. This is also true in MSVC. When compiling the above code in MSCV 2010 with warnings enabled you get:

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

The compiler actually ignores double after unsigned, making your a actually an unsigned int.

If you try the following:

unsigned double a = 1.0;

You actually get two warnings:

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

Interestingly, there is no C4076 warning in MSDN for VS2010. It is present only for VS2005 and VS2008.

CygnusX1
  • 20,968
  • 5
  • 65
  • 109
  • 7
    @satuon I bet a stubborn MSVC developer had a large code-base in which they had thought `unsigned double` was a thing and then, when they realised it wasn't, they didn't want to break their code. – Joseph Mansfield Feb 20 '13 at 10:38
  • 2
    In VS2010, if you select the warning in the Output pane and press F1, it takes you to the [2010 documentation for the warning](http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k%28C4076%29;k%28VS.OUTPUT%29;k%28DevLang-%22C%2B%2B%22%29&rd=true). – Clifford Feb 20 '13 at 10:51
  • 1
    It's not an error because the compiler can work around it. That's all warnings are: errors the compiler can ignore. –  Feb 20 '13 at 12:02
  • 7
    @sftrabbit One has to wonder how their codebase would have worked at all, considering they were using an unsigned integer as a floating-point type. – Thomas Feb 20 '13 at 12:18
  • @James - some warnings are not "errors the compiler can ignore"; they're stupid attempts to enforce coding style. Gcc has recently added a warning about this code: `a && b || c && d` that you should add parentheses. The first thing I do in any project is turn off that warning. (the compiler doesn't warn about a * b + c * d`). – Pete Becker Feb 20 '13 at 13:59
  • 23
    @PeteBecker Not stupid. Warnings are generally made for issues that have in the past led to bugs. No one in high school or above will get confused about + vs * precedence; the same cannot be said for && vs ||. I was programming (and being confused about their precedence) long before I learned formal logic. – Sebastian Redl Feb 20 '13 at 14:08
  • 4
    @SebastianRedl - sorry, but I don't agree that programmers have to be protected from their own misunderstandings. If you don't know how to write logical expressions without adding unnecessary parentheses, take the time to learn it. A warning that says to add parentheses is giving bad advice. – Pete Becker Feb 20 '13 at 14:35
  • 14
    @PeteBecker You're welcome to disable the warning and tell the people in your programming teams that they have to learn the precedence by heart. That's really your choice, assuming you actually have that kind of power wherever you work. But the reality is that this has been a source of bug and will continue to be a source of bugs, so don't call the warning stupid. – Sebastian Redl Feb 20 '13 at 14:37
  • 3
    @SebastianRedl - again: the warning says to **add parentheses**. That's **bad advice**; writing correct logical expressions is not hard, and learning how to use the language correctly is much better than applying hacks to avoid learning. As to where I work, unfortunately, when writing the standard library, it's a major headache to manage warnings like that; the effect of this warning is to **require** parentheses in library code. – Pete Becker Feb 20 '13 at 15:13
  • 9
    @PeteBecker Do the parentheses actually cause any problems then? Do they not get optimised out anyway when compiling? If they don't cause problems, and don't even make any difference to compiled code, then all they do is make things clearer for people reading the code, which is a good thing, no? – Matt Fellows Feb 20 '13 at 15:25
  • 5
    @MattFellows - it depends on where you add the parentheses. ``. If you change `a && b || c && d` to `(a && b) || (c && d)` they do not change the meaning of the code. They do, however, make it harder for professional programmers to read, because they indicate that the code is doing something out of the ordinary; otherwise they wouldn't be there. Mixing up precedences is a beginners mistake; blanket advice telling beginners to add parentheses only compounds the problem. – Pete Becker Feb 20 '13 at 15:48
  • 16
    @PeteBecker - I understand and agree with your point about the warning not really being a warning. But to say that it is easier to understand the line of code without parenthesis for a 'professional programmer' is simply wrong. I have been a professional programmer for 15 years and know the rules of precedence. Both lines of code in your example are equally clear to me. Adding parenthesis for clarification (just like mathematicians do) does not make it harder for me to read and understand. – CramerTV Feb 20 '13 at 17:45
  • 2
    Wow. OK, use parentheses for clarity when your group isn't a bunch of algebraists (though some are). And `&&` has precedence over `||` because `&&` is multiplicative: it has a multiplicative zero (false) and a multiplicative identity (true); while `||` is additive in that it has an additive identity (false). – minopret Feb 20 '13 at 18:01
  • 4
    @CramerTV - to paraphrase a statement in an earlier question on SO: `return ((a – Pete Becker Feb 20 '13 at 18:01
  • 10
    @PeteBecker - return (a || b && c < d + e * f + ++g - h--); No parens needed here either. Is this really as clear as the non-minimal version? Reductio ad absurdum. Can't argue with ideologues - I'm out. – CramerTV Feb 20 '13 at 19:43
  • 6
    There is also a warning if you write `if (a=5)` instead of `if (a==5)` and you need an extra parenthesis to get rid of the warning if you meant it to be an assignment. Is it needed? No. But it is a commons source of errors even among professional programmers who know the difference between `=` and `==`. – CygnusX1 Feb 20 '13 at 20:01
26

If you set the warning level higher (/W3 in my test), you will get an appropriate warning:

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

If you then use the debugger to inspect the variable, all becomes clear:

enter image description here

You can see that the variable is in fact an unsigned int

Clifford
  • 88,407
  • 13
  • 85
  • 165
23

Combining unsigned with double in the declaration specifier sequence is not valid C++. This must be an MSVC extension (or bug) of some sort.

As a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration or in a type-specifier-seq or trailing-type-specifier-seq. The only exceptions to this rule are the following:

  • const can be combined with any type specifier except itself.
  • volatile can be combined with any type specifier except itself.
  • signed or unsigned can be combined with char, long, short, or int.
  • short or long can be combined with int.
  • long can be combined with double.
  • long can be combined with long.
Community
  • 1
  • 1
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
4

Unsigned and signed act as type qualifiers in MSVC where possible (unsigned char, signed short etc). If it's impossible to do that, such as unsigned bool, or signed double, the requested type is not created. And the type is just treated as unsigned [int] and signed [int].

talonmies
  • 70,661
  • 34
  • 192
  • 269
Boyko Perfanov
  • 3,007
  • 18
  • 34
  • 8
    Which is _not_ legal C++. A C++ compiler _must_ issue a diagnostic for the posted code. (And to be frank, if this is an extension, rather than an error, it is a stupid one.) – James Kanze Feb 20 '13 at 10:33
  • 1
    It's probably a warning due to having to scrape the header files from a large pre-existing codebase (most likely in C). If I were writing a C++ compiler I'd wave lots of things that would have been legal in C when reading in .h files that don't contain any C++ constructs. – Joshua Feb 20 '13 at 18:12
  • @Joshua: `unsigned double` is invalid in both C and C++. – Keith Thompson Feb 20 '13 at 19:13
  • Yes, but it compiles in old C as "unsigned". – Joshua Feb 20 '13 at 21:22
2

It is a bug in VS2010. VS2012 gives the following error for that line of code.

error CS1002: ; expected

It is expecting a ';' before the keyword 'double'.

CramerTV
  • 1,376
  • 1
  • 16
  • 29