9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] 8c puzzling behavior
@ 2011-03-08 17:16 erik quanstrom
  2011-03-08 20:21 ` geoff at plan9.bell-labs.com
  2011-03-08 23:32 ` Bakul Shah
  0 siblings, 2 replies; 8+ messages in thread
From: erik quanstrom @ 2011-03-08 17:16 UTC (permalink / raw)


for this

	uvlong u, i;

	i = 31;
	u = 0xff00000000000000ull;

i get

	u & 1<<i		-> 0xff00000000000000ull
	u & 0x80000000		-> 0
	u & (int)0x80000000	-> 0xff00000000000000ull
	u & -2147483648		-> 0

to put a finer point on it,

	(uvlong)(1<<i)		-> 0xffffffff80000000
	(uvlong)(0x80000000)	-> 0x80000000
	(uvlong)(int)0x80000000	-> 0xffffffff80000000
	(uvlong)-2147483648	-> 0x80000000

so it seems clear that constants are treated as if unsigned, regardless,
but variables are not?

can this be correct?  i hate to hazzard guesses about the c standard.

- erik



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [9fans] 8c puzzling behavior
  2011-03-08 17:16 [9fans] 8c puzzling behavior erik quanstrom
@ 2011-03-08 20:21 ` geoff at plan9.bell-labs.com
  2011-03-08 23:32 ` Bakul Shah
  1 sibling, 0 replies; 8+ messages in thread
From: geoff at plan9.bell-labs.com @ 2011-03-08 20:21 UTC (permalink / raw)


If signedness matters, I use 1u or 1ul or 1ull.  Doing so
will make your examples work as expected.

I don't pretend to understand the ansi rules and don't want
to devote the time to try to decode them.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [9fans] 8c puzzling behavior
  2011-03-08 17:16 [9fans] 8c puzzling behavior erik quanstrom
  2011-03-08 20:21 ` geoff at plan9.bell-labs.com
@ 2011-03-08 23:32 ` Bakul Shah
  2011-03-08 23:54   ` erik quanstrom
  1 sibling, 1 reply; 8+ messages in thread
From: Bakul Shah @ 2011-03-08 23:32 UTC (permalink / raw)


On Tue, 08 Mar 2011 12:16:29 EST erik quanstrom <quanstro at quanstro.net>  wrote:
> for this
> 
> 	uvlong u, i;
> 
> 	i = 31;
> 	u = 0xff00000000000000ull;
> 
> i get
> 
> 	u & 1<<i		-> 0xff00000000000000ull
> 	u & 0x80000000		-> 0
> 	u & (int)0x80000000	-> 0xff00000000000000ull
> 	u & -2147483648		-> 0
> 
> to put a finer point on it,
> 
> 	(uvlong)(1<<i)		-> 0xffffffff80000000
> 	(uvlong)(0x80000000)	-> 0x80000000
> 	(uvlong)(int)0x80000000	-> 0xffffffff80000000
> 	(uvlong)-2147483648	-> 0x80000000
> 
> so it seems clear that constants are treated as if unsigned, regardless,
> but variables are not?
> 
> can this be correct?  i hate to hazzard guesses about the c standard.

1 is signed. 1u is unsigned (see 6.4.4.1). 0x80000000 doesn't
fit in an int so it is an unsigned int. 0x100000000 won't fit
in an unsigned int so it will pick the next type in the table
that is big enough, which is long long int. Nice, eh?!

For shift operators, type of the result is that of the
"promoted left operand" (see 6.5.7). So 1<<i is an int.
It is first promoted to a long long int and then to
unsigned long long int.

As for conversions, a smaller sized (lower ranked) value is
first converted to a larger sized (higher ranked) value of the
*same* type before any signedness conversion but can't find
where it says so in the std. May be 6.3.1.1.

The value of (int)0x80000000 is an unsigned int to int
conversion and since its value doesn't fit in an int, the
result is implementation defined. Usually it just becomes
-2147483648 (since that is more efficient than anything else).

Both clang and gcc fail the following (but I can well believe
plan9 C compiler behaves differently).

> 	u & -2147483648		-> 0
> 	(uvlong)-2147483648	-> 0x80000000

-2147483648 is first converted to long long int (preserving
its value) and then to unsigned long long int. So this is
0xffffffff80000000ull.

---

#define check(x) do if (!(x)) printf("%s:%d: check failed: %s\n", __FILE__, __LINE__, #x); while(0)

typedef unsigned long long uvlong;

int main()
{
	uvlong i = 31;
	uvlong u = 0xff00000000000000ull;

	check((u & 1<<i)              == 0xff00000000000000ull);
	check((u & 0x80000000)        == 0);
	check((u & (int)0x80000000)   == 0xff00000000000000ull);
	check((u & -2147483648)       == 0);

	check((uvlong)(1<<i)          == 0xffffffff80000000ull);
	check((uvlong)(0x80000000)    == 0x80000000ull);
	check((uvlong)(int)0x80000000 == 0xffffffff80000000ull);
	check((uvlong)-2147483648     == 0x80000000ull);
	check((uvlong)-2147483648     == 0xffffffff80000000ull);
	return 0;
}



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [9fans] 8c puzzling behavior
  2011-03-08 23:32 ` Bakul Shah
@ 2011-03-08 23:54   ` erik quanstrom
  2011-03-09  7:23     ` Charles Forsyth
  0 siblings, 1 reply; 8+ messages in thread
From: erik quanstrom @ 2011-03-08 23:54 UTC (permalink / raw)


> 1 is signed. 1u is unsigned (see 6.4.4.1). 0x80000000 doesn't
> fit in an int so it is an unsigned int. 0x100000000 won't fit
> in an unsigned int so it will pick the next type in the table
> that is big enough, which is long long int. Nice, eh?!

ah!  i had just forgotten about the "too big to fit into an int,
make unsigned" rule.  it all makes sense, now.  but man is it
annoying to convert code from 32 to 64 bits.

you hear bats. you feel a draft. you smell a wumpus.  ...
ah, that's the c type system.

- erik



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [9fans] 8c puzzling behavior
  2011-03-08 23:54   ` erik quanstrom
@ 2011-03-09  7:23     ` Charles Forsyth
  2011-03-09 13:05       ` erik quanstrom
  0 siblings, 1 reply; 8+ messages in thread
From: Charles Forsyth @ 2011-03-09  7:23 UTC (permalink / raw)


>ah, that's the c type system.

not exactly: ansi changed it.
the original one had unsigned as an attribute that remained despite changes of word length.
ansi changed it for various reasons to `value preserving' from `unsigned preserving'.



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [9fans] 8c puzzling behavior
  2011-03-09  7:23     ` Charles Forsyth
@ 2011-03-09 13:05       ` erik quanstrom
  0 siblings, 0 replies; 8+ messages in thread
From: erik quanstrom @ 2011-03-09 13:05 UTC (permalink / raw)


On Wed Mar  9 02:11:21 EST 2011, forsyth at terzarima.net wrote:
> >ah, that's the c type system.
> 
> not exactly: ansi changed it.
> the original one had unsigned as an attribute that remained despite changes of word length.
> ansi changed it for various reasons to `value preserving' from `unsigned preserving'.

i was meckering about the current state of affairs,
not casting aspersions on the original.

- erik



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [9fans] 8c puzzling behavior
  2011-03-08 17:21 erik quanstrom
@ 2011-03-08 17:43 ` Lucio De Re
  0 siblings, 0 replies; 8+ messages in thread
From: Lucio De Re @ 2011-03-08 17:43 UTC (permalink / raw)


>> so it seems clear that constants are treated as if unsigned, regardless,
>> but variables are not?
> 
> the really wierd bit is that the 1 in 1<<i suddenly becomes signed,
> even though other constants are treated as if unsigned, and i is
> unsigned.
> 
I would not hesitate to call that a bug.

I would also strongly advise you to leave well enough alone and not
rely on what the standard calls implementation choices for any code
you would like to be portable.  If it doesn't have to be portable,
check the compiler behaviour; then, as R.A. Heinlein would have it,
"revel in it".

++L




^ permalink raw reply	[flat|nested] 8+ messages in thread

* [9fans] 8c puzzling behavior
@ 2011-03-08 17:21 erik quanstrom
  2011-03-08 17:43 ` Lucio De Re
  0 siblings, 1 reply; 8+ messages in thread
From: erik quanstrom @ 2011-03-08 17:21 UTC (permalink / raw)


> so it seems clear that constants are treated as if unsigned, regardless,
> but variables are not?

the really wierd bit is that the 1 in 1<<i suddenly becomes signed,
even though other constants are treated as if unsigned, and i is
unsigned.

- erik



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-03-09 13:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-08 17:16 [9fans] 8c puzzling behavior erik quanstrom
2011-03-08 20:21 ` geoff at plan9.bell-labs.com
2011-03-08 23:32 ` Bakul Shah
2011-03-08 23:54   ` erik quanstrom
2011-03-09  7:23     ` Charles Forsyth
2011-03-09 13:05       ` erik quanstrom
2011-03-08 17:21 erik quanstrom
2011-03-08 17:43 ` Lucio De Re

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).