Skip to contentSkip to conversation

Compiling kernel with SuSE 8.2/gcc 3.3

DISCUSSION Andi Kleen 6 participants 6 messages Jun 11, 2003 – Jun 12, 2003 1 message not in the archive

lore
Share & tools
lore

Andi Kleen

author
#1 lore raw
In reply to a message not in the archive
Quoted 4 lines · Steve French

look wrong for gcc to spit out warnings on. For example the following
local variable definition and the similar ones in the same file (fs/cifs/inode.c):

Quoted 8 lines
	__u64 uid = 0xFFFFFFFFFFFFFFFF;

generates a warning saying the value is too long for a long on x86 SuSE 8.2 with gcc 3.3 - which makes no sense. Any value above 0xFFFFFFFFF generates the same warning (intuitively 36 bits should fit in an unsigned 64 bit local variable).

Defining the literal with the UL suffix didn't seem to help - and I

Define it with ULL (= long long)

Quoted 2 lines

Any idea what is going on in this weird gcc 3.3 behavior where it thinks 64 bits can't fit in a __u64 local variable? -

AFAIK the problem is that it has no default promotion for constants to long long (normally they are int, long, unsigned long etc. depending on their value) It's some C99 thing. Or maybe a gcc bug. Anyways ULL makes it clear that it is unsigned long long.

-Andi

P.S.: The warning is thankfully turned off by default again in later compilers.

#2 lore raw

Although it fixes it for building on 32 bit architectures, won't changing

	__u64 uid = 0xFFFFFFFFFFFFFFFF;

to

	__u64 uid = 0xFFFFFFFFFFFFFFFFULL;

generate a type mismatch warning on ppc64 and similar 64 bit
architecutres since __u64 is not a unsigned long long on ppc64 (it is unsigned long)? My gut reaction is to just ingore the three
places that cause warnings and the remaining two places that cause signed/unsigned compare warnings of unsigned int local variables to #defined literals (which presumably are treated as signed by default).

Quoted 17 lines · Andi Kleen
Quoted 8 lines · Steve French

... and the similar ones in the same file
(fs/cifs/inode.c):

	__u64 uid = 0xFFFFFFFFFFFFFFFF;

generates a warning saying the value is too long for a long on x86 SuSE 8.2 with gcc 3.3

Define it with ULL (= long long)

AFAIK the problem is that it has no default promotion for constants to long long (normally they are int, long, unsigned long etc. depending on their value) It's some C99 thing. Or maybe a gcc bug. Anyways ULL makes it clear that it is unsigned long long.

#3 lore raw

Review

Quoted 12 lines · Steve French

Although it fixes it for building on 32 bit architectures, won't changing

(quoted diff) +0 -0
 	__u64 uid = 0xFFFFFFFFFFFFFFFF;
 to
 
 	__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
 
 generate a type mismatch warning on ppc64 and similar 64 bit
 architecutres since __u64 is not a unsigned long long on ppc64 
 (it is unsigned long)?
	u64 uid = -1;

will work just nicely.

#5 lore raw
In reply to Steve French

In article <[email protected]>,

Quoted 11 lines · Steve French

Although it fixes it for building on 32 bit architectures, won't changing

	__u64 uid = 0xFFFFFFFFFFFFFFFF;

to

	__u64 uid = 0xFFFFFFFFFFFFFFFFULL;

generate a type mismatch warning on ppc64 and similar 64 bit architecutres since __u64 is not a unsigned long long on ppc64 (it is unsigned long)?

No, why would it?

If you do

	char c = 1;

do you expect a warning? The right side of the assignent is an "int", and the left side is a "char", but it's perfectly ok to assign a wider type to a narrower one.

And so if "__u64" were to be a plain "unsigned long" on a 64-bit architecture (and even if "unsigned long long" were to be 128 bits), the constant 0xFFFFFFFFFFFFFFFFULL is (a) a perfectly valid unsigned long long value and (b) fits perfectly well even in an "unsigned long", so the compiler has no reason to complain about the assignment losing bits (which it otherwise might do).

So I'd much rather make the constants too big than too small. And yes, Andrew's suggestion about just assigning -1 works, but it's actually a very subtle cast at that point.

Linus

#4 lore raw
In reply to Andrew Morton

Hi Andrew.

Quoted 9 lines
Quoted 9 lines

Although it fixes it for building on 32 bit architectures, won't changing

	__u64 uid = 0xFFFFFFFFFFFFFFFF;

to

	__u64 uid = 0xFFFFFFFFFFFFFFFFULL;
Quoted 7 lines
Quoted 3 lines

generate a type mismatch warning on ppc64 and similar 64 bit architectures since __u64 is not a unsigned long long on ppc64 (it is unsigned long)?

	u64 uid = -1;

will work just nicely.

Won't that generate a warning about assigning a signed quantity to an unsigned variable?

What's really needed is a set of definitions along the lines of

	#define MAX_U32	((__u32) 0xFFFFFFFFUL)
	#define MAX_U64	((__u64) 0xFFFFFFFFFFFFFFFFULL)

but as an intermediate measure, how about...

	__u64 uid = ((__u64) 0xFFFFFFFFFFFFFFFFULL);

Best wishes from Riley.
---
* Nothing as pretty as a smile, nothing as ugly as a frown.

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.488 / Virus Database: 287 - Release Date: 5-Jun-2003

#6 lore raw
In reply to Steve French
Quoted 6 lines · Steve French

Although it fixes it for building on 32 bit architectures, won't changing

	__u64 uid = 0xFFFFFFFFFFFFFFFF;

to

Quoted 8 lines
	__u64 uid = 0xFFFFFFFFFFFFFFFFULL;

generate a type mismatch warning on ppc64 and similar 64 bit architecutres since __u64 is not a unsigned long long on ppc64 (it is unsigned long)? My gut reaction is to just ingore the three places that cause warnings and the remaining two places that cause signed/unsigned compare warnings of unsigned int local variables to #defined literals (which presumably are treated as signed by default).

Be careful, the value will get shoehorned into 4 bytes to make the int constant, which is then assigned to the __u64.

Signature · 4 lines
Dr. Horst H. von Brand                   User #22616 counter.li.org
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513