S
Skybuck Flying
warning C4146: unary minus operator applied to unsigned type, result still
unsigned.
?
unsigned.
?
Skybuck Flying said:warning C4146: unary minus operator applied to unsigned type, result still
unsigned.
?
warning C4146: unary minus operator applied to unsigned type, result
still unsigned.
?
I guess you have 32-bit ints with 2's complement.warning C4146: unary minus operator applied to unsigned type, result still
unsigned.
?
But that question and its answer could be also interesting for<snip>
Skybuck is a troll. If you need evidence just look at his recent posts
in alt.lang.asm. It like a tornado has come and gone.
But that question and its answer could be also interesting for
people other than him.
I guess you have 32-bit ints with 2's complement.
The C99 rationale (6.4.4.4.)says "Notwithstanding the general rule
that literal constants are non-negative, 3..." where the footnote
is "3 Note that -4 is an expression: unary minus with operand 4.".
INT_MAX is 0x7FFFFFFF, so a decimal constant of 0x80000000 doesn't
fit in a signed int, and if INT_MAX == LONG_MAX, not even in a
signed long. In C89 this would cause it to have unsigned type.
Negating it yields UINT_MAX + 1 - 0x80000000 which is 0x80000000,
which doesn't fit in a signed int.
Try using:
long a = -2147483647 - 1, for example MSVC #define's INT_MIN this
way (but with parentheses around it). Note that in C89 no type is
*required* to be able to hold that value, so the program won't be
portable everywhere. But using long will make it portable even on
systems with 16-bit int, provided they use two's complement.
(Or INT_MIN if you mean that. If you have C99 maybe you want to
use INT32_MIN and declare a as an int32_t, these are defined in
<stdint.h>.)
Barry said:If a constant won't fit in an int, the next type considered is an
unsigned int. Only if it won't fit in that either is long considered.
See the table in n1124, section 6.4.4.1, paragraph 5.
In this particular situation, it goes to unsigned int regardless of
LONG_MAX.
Evaluating UINT_MAX+1 produces 0 which will fit in an int. The point
of the diagnostic is that negating a positive value is producing
another positive value.
Given your 32 bit assumption, a could be an int in this expression. It
is the numeric literal that is "causing the problem." Literals have
the "smallest" type (starting with int) which will contain them.
2147483648 will not fit in an int (in this case) but will in an
unsigned int. Therefore, it has that type which results in the
diagnostic.
2147483647 will fit in an int, as will 1, so all the
operands in your expression are int and the arithmetic is performed on
that type. Since the result is also a valid int, everything works as
expected.
On a C89 system with 32-bit long and no long long, evaluating the
expression -2147483647-1 and assigning it to a signed integer produces
undefined behavior.
santosh said:<snip>
Skybuck is a troll. If you need evidence just look at his recent posts
in alt.lang.asm. It like a tornado has come and gone.
Barry said:.... snip ...
On a C89 system with 32-bit long and no long long, evaluating the
expression -2147483647-1 and assigning it to a signed integer
produces undefined behavior.
What did you think I meant by INT_MAX == LONG_MAX above?Barry Schwarz said:If a constant won't fit in an int, the next type considered is an
unsigned int. Only if it won't fit in that either is long considered.
I meant the number UINT_MAX + 1 - 2^31, with its mathematicalSee the table in n1124, section 6.4.4.1, paragraph 5.
In this particular situation, it goes to unsigned int regardless of
LONG_MAX.
Evaluating UINT_MAX+1 produces 0 which will fit in an int. The point
of the diagnostic is that negating a positive value is producing
another positive value.
If INT_MAX == LONG_MAX (as I have assumed, see above) it won't fitHarald van D?k said:That applies to octal and hexadecimal constants. 0x80000000 is a hexadecimal
constant, but see below.
I assume the mathematical value of UINT_MAX + 1 - 0x80000000 was meant. Yes.
2147483648 will not fit in an int, but will in a long. Whether it fits in an
unsigned int does not matter.
Army1987 said:If INT_MAX == LONG_MAX (as I have assumed, see above) it won't fit
in a signed long. In C99 it'd be a signed long long, but in C89 it
must be unsigned.
CBFalconer said:Not when the arithmetic is 2's complement. As this is used in the
definition of INT_MIN by the implementor, he is allowed to know
this.
That applies to octal and hexadecimal constants. 0x80000000 is a hexadecimal
constant, but see below.
Ah yes, if it also doesn't fit in long, it won't have type long, of course.
I missed that assumption.
But in C89/C90, it still won't have type unsigned. It will have type
unsigned long. An unsuffixed decimal literal can never have a type of
unsigned int.
I said a *decimal* constant of 0x80000000, that is the literalThat applies to octal and hexadecimal constants. 0x80000000 is a hexadecimal
constant, but see below.
Like this:How do we know how the implementor defines INT_MIN?
Army1987 said:On Sun, 08 Jul 2007 13:31:55 -0700, Keith Thompson wrote:
[snip]Like this:How do we know how the implementor defines INT_MIN?
#include <stdio.h>
#include <limits.h>
#define STR(x) STR_(x)
#define STR_(x) #x
int main(void)
{
puts(STR(INT_MIN));
return 0;
}
It is a strictly conforming program.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.