int a = -2147483648;

S

Skybuck Flying

warning C4146: unary minus operator applied to unsigned type, result still
unsigned.

?
 
M

methione

Skybuck Flying said:
warning C4146: unary minus operator applied to unsigned type, result still
unsigned.

?

too large value for signed integer (check integer boundary)
 
R

Richard Heathfield

Skybuck Flying said:
warning C4146: unary minus operator applied to unsigned type, result
still unsigned.

?

warning CLC123: longstanding troll returns to comp.lang.c - suggest
archive check before composing reply.
 
A

Army1987

warning C4146: unary minus operator applied to unsigned type, result still
unsigned.

?
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>.)
 
S

santosh

<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.
 
A

Army1987

<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.
 
K

Kenny McCormack

But that question and its answer could be also interesting for
people other than him.

That doesn't (wouldn't) matter to the anti-troll brigade.
 
B

Barry Schwarz

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

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.
signed long. In C89 this would cause it to have unsigned type.

In this particular situation, it goes to unsigned int regardless of
LONG_MAX.
Negating it yields UINT_MAX + 1 - 0x80000000 which is 0x80000000,
which doesn't fit in a signed int.

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.
Try using:
long a = -2147483647 - 1, for example MSVC #define's INT_MIN this

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.
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.

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.
(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>.)


Remove del for email
 
H

Harald van =?UTF-8?B?RMSzaw==?=

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.

That applies to octal and hexadecimal constants. 0x80000000 is a hexadecimal
constant, but see below.
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.

I assume the mathematical value of UINT_MAX + 1 - 0x80000000 was meant.
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.

2147483648 will not fit in an int, but will in a long. Whether it fits in an
unsigned int does not matter.
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.

With the stated assumption (two's complement), -2147483647-1 is not out of
the range of long, so assigning it to a long produces no undefined
behaviour. Did you perhaps mean "int" instead of "integer"? If you did,
that's why long would be used.
 
D

Default User

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.

Maybe all this talk of killfiles woke him up.




Brian
 
C

CBFalconer

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.

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.
 
A

Army1987

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.
What did you think I meant by INT_MAX == LONG_MAX above?
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.
I meant the number UINT_MAX + 1 - 2^31, with its mathematical
meaning, not the C expression (UINT_MAX + 1) - 0x80000000.
I was alluding to reduction modulo UINT_MAX + 1, which is obviously
not reduction modulo 0.
[snip]
 
A

Army1987

Harald 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.
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.
[snip]
 
H

Harald van =?UTF-8?B?RMSzaw==?=

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.

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.
 
K

Keith Thompson

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.


How do we know how the implementor defines INT_MIN?

If we know that the *value* of INT_MIN is (mathematically)
-2147483648, that does tell us that we can assign the result of the
expression -2147483647-1 to a signed int (N.B.: int, not integer).

Of course, if we're assuming 32-bit two's-complement, it would be
easier to write
int a = INT_MIN;
And if we're not assuming 32-bit two's-complement, then
int a = -2147483648;
can invoke undefined behavior, either if int is smaller than 32 bits
or if it uses a representation other than two's-complement.
 
B

Barry Schwarz

That applies to octal and hexadecimal constants. 0x80000000 is a hexadecimal
constant, but see below.

Your right. I skipped a heading in the table. I'd like to blame
Acrobat Reader but it's my own damn fault.© I wish I could cancel my
previous message in this but the best I can suggest is that everyone
ignore it.


Remove del for email
 
A

Army1987

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.

Er... Right. Just replace "int" with "long" in some places above.
If INT_MAX = LONG_MAX = 2147483647, then 2147483648 won't fit in
an int, it won't fit in a long, and (in C89) will then have type
unsigned long. So the expression -2147483648 is reduced modulo
ULONG_MAX + 1 (the mathematical value, 4294967296), [1] and equals
2147483648, which doesn't fit in an int. A warning is issued and
the result is implementation-defined. (Likely -2147483648
indeed... But at least #define INT_MIN (-2147483647 - 1)
eliminates that warning.)

[1] Assuming signed long has no more padding than unsigned long.
 
A

Army1987

That applies to octal and hexadecimal constants. 0x80000000 is a hexadecimal
constant, but see below.
I said a *decimal* constant of 0x80000000, that is the literal
2147483648. I just wrote it in hex because I don't remember its
decimal digits by heart and I didn't think about copy&paste.
 
A

Army1987

On Sun, 08 Jul 2007 13:31:55 -0700, Keith Thompson wrote:
[snip]
How do we know how the implementor defines INT_MIN?
Like this:
#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.
 
J

Jean-Marc Bourguet

Army1987 said:
On Sun, 08 Jul 2007 13:31:55 -0700, Keith Thompson wrote:
[snip]
How do we know how the implementor defines INT_MIN?
Like this:
#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.

No. It's output is implementation dependant.

Yours,
 

Ask a Question

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.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top