Re: unary minus operator applied to unsigned type, result still unsigned?
- From
Philip Oakley <philipoakley@iee.org>
- Date
- May 5, 2016, 21:39 UTC
- Message-ID
- <D165B5E4FA8947DD8A5F18B7A15B02BC@PhilipOakley>
- In-Reply-To
- <xmqqoa8lcswz.fsf@gitster.mtv.corp.google.com>
From: "Junio C Hamano" <gitster@pobox.com>
Show 37 quoted lines
> "Philip Oakley" <philipoakley@iee.org> writes: > >> I'm working on building Git on Visual Studio as part of the Git for >> Windows >> capability. >> >> The MSVC compiler is reporting: >> >> 1>..\sha1-lookup.c(100) : warning C4146: unary minus operator applied to >> unsigned type, result still unsigned > >> 1>..\sha1-lookup.c(316) : warning C4146: unary minus operator applied to >> unsigned type, result still unsigned >> >> the two lines of code are the same, and the message suggests a bad >> return value: >> >> #100: return -lo-1; >> >> #316: return -lo-1; >> >> >> Should these be protected by an appropriate brackets/calculation >> (-1-lo) ? Or does >> gcc use an alternate assumption about unary minus conversion for >> functions >> returning int? > > I think -lo-1 (which is carried out as unsigned) is further casted > back to signed int as part of the return from the function whose > type is signed int. This may be portable in practice, but changing > type of lo to signed int may be prudent. > > sha1_pos() uses size_t, but returns "int", which is inconsistent > (size_t could be much larger). Either using int for hi/lo/mi, or > using ssize_t and returning ssize_t would make sense. >
I'm going to hold off on patching this at the moment, as there are a few more signed/unsigned mismatches that are reported but I've been ignoring (mainly comparisons), so I'll try and catch them all at the same time, especially as I now understand the standards issues.
This thread has a summary of the standards http://stackoverflow.com/questions/8026694/c-unary-minus-operator-behavior-with-unsigned-operands (includes C++ >> C) while https://msdn.microsoft.com/en-us/library/4kh09110(v=vs.90).aspx explains what is being reported.
i.e. unary minus on unsigned ints produces the 2's complement + 1 value, except for 0x8000h, where that would be out of range. It's an oddball of partially defined behaviours. -- Philip