login
Header Space

 
 

Linux: Dropping Support for GCC 2.95

December 13, 2005 - 12:20pm
Submitted by Jeremy on December 13, 2005 - 12:20pm.
Linux news

Four months ago a debate on the lkml suggested that support for GCC 2.95 would be around for a long time [story], but a more recent thread suggests otherwise. 2.6 maintainer Andrew Morton put together a small patch to remove support for 2.95, and discussion continued to explore which versions of GCC 3.x should be supported. Andrew explained:

"2.95.x is basically buggered at present. There's one scsi driver which doesn't compile due to weird __VA_ARGS__ tricks and the rather useful scsi/sd.c is currently getting an ICE. None of the new SAS code compiles, due to extensive use of anonymous unions. The V4L guys are very good at exploiting the gcc-2.95.x macro expansion bug (_why_ does each driver need to implement its own debug macros?) and various people keep on sneaking in anonymous unions.

"It's time to give up on it and just drink more coffee or play more tetris or something, I'm afraid."


From: Andi Kleen [email blocked]
To: Ingo Molnar [email blocked]
Subject: Re: [PATCH 1/19] MUTEX: Introduce simple mutex implementation
Date:	Tue, 13 Dec 2005 08:58:35 +0100

> - i introduced a 'type-sensitive' macro wrapper that switches down() 
>   (and the other APIs) to either to the assembly variant (if the 
>   variable's type is struct compat_semaphore), or switches it to the new 
>   generic mutex (if the type is struct semaphore), at build-time. There 
>   is no runtime overhead due to this build-time-switching.

Didn't that drop compatibility with 2.95?  The necessary builtins
are only in 3.x. 

Not that I'm not in favour - I would like to use C99 everywhere 
and it would get of the ugly spinlock workaround for i386
and x86-64 doesn't support earlier compilers anyways - 
but others might not agree.

-Andi


From: Andrew Morton [email blocked] Subject: Re: [PATCH 1/19] MUTEX: Introduce simple mutex implementation Date: Tue, 13 Dec 2005 00:42:57 -0800 Andi Kleen [email blocked] wrote: > > > - i introduced a 'type-sensitive' macro wrapper that switches down() > > (and the other APIs) to either to the assembly variant (if the > > variable's type is struct compat_semaphore), or switches it to the new > > generic mutex (if the type is struct semaphore), at build-time. There > > is no runtime overhead due to this build-time-switching. > > Didn't that drop compatibility with 2.95? The necessary builtins > are only in 3.x. > > Not that I'm not in favour - I would like to use C99 everywhere > and it would get of the ugly spinlock workaround for i386 > and x86-64 doesn't support earlier compilers anyways - > but others might not agree. > 2.95.x is basically buggered at present. There's one scsi driver which doesn't compile due to weird __VA_ARGS__ tricks and the rather useful scsi/sd.c is currently getting an ICE. None of the new SAS code compiles, due to extensive use of anonymous unions. The V4L guys are very good at exploiting the gcc-2.95.x macro expansion bug (_why_ does each driver need to implement its own debug macros?) and various people keep on sneaking in anonymous unions. It's time to give up on it and just drink more coffee or play more tetris or something, I'm afraid.
From: Andi Kleen [email blocked] Subject: Re: [PATCH 1/19] MUTEX: Introduce simple mutex implementation Date: Tue, 13 Dec 2005 09:49:26 +0100 > It's time to give up on it and just drink more coffee or play more tetris > or something, I'm afraid. Or start using icecream (http://wiki.kde.org/icecream) Anyways cool. Gratulations. Can you please apply the following patch then? Remove -Wdeclaration-after-statement Now that gcc 2.95 is not supported anymore it's ok to use C99 style mixed declarations everywhere. Signed-off-by: Andi Kleen [email blocked] Index: linux/Makefile =================================================================== --- linux/Makefile +++ linux/Makefile @@ -535,9 +535,6 @@ include $(srctree)/arch/$(ARCH)/Makefile NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) CHECKFLAGS += $(NOSTDINC_FLAGS) -# warn about C99 declaration after statement -CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) - # disable pointer signedness warnings in gcc 4.0 CFLAGS += $(call cc-option,-Wno-pointer-sign,)
From: Andrew Morton [email blocked] Subject: Re: [PATCH 1/19] MUTEX: Introduce simple mutex implementation Date: Tue, 13 Dec 2005 01:01:26 -0800 Andi Kleen [email blocked] wrote: > > Can you please apply the following patch then? > > Remove -Wdeclaration-after-statement OK. Thus far I have this: From: Andrew Morton [email blocked] There's one scsi driver which doesn't compile due to weird __VA_ARGS__ tricks and the rather useful scsi/sd.c is currently getting an ICE. None of the new SAS code compiles, due to extensive use of anonymous unions. The V4L guys are very good at exploiting the gcc-2.95.x macro expansion bug (_why_ does each driver need to implement its own debug macros?) and various people keep on sneaking in anonymous unions. Plus anonymous unions are rather useful. Signed-off-by: Andrew Morton [email blocked] --- dev/null | 29 ----------------------------- include/linux/compiler.h | 2 -- init/main.c | 7 +------ 3 files changed, 1 insertion(+), 37 deletions(-) diff -puN init/main.c~abandon-gcc-295x init/main.c --- devel/init/main.c~abandon-gcc-295x 2005-12-13 00:48:17.000000000 -0800 +++ devel-akpm/init/main.c 2005-12-13 00:48:17.000000000 -0800 @@ -58,11 +58,6 @@ * This is one of the first .c files built. Error out early * if we have compiler trouble.. */ -#if __GNUC__ == 2 && __GNUC_MINOR__ == 96 -#ifdef CONFIG_FRAME_POINTER -#error This compiler cannot compile correctly with frame pointers enabled -#endif -#endif #ifdef CONFIG_X86_LOCAL_APIC #include <asm/smp.h> @@ -74,7 +69,7 @@ * To avoid associated bogus bug reports, we flatly refuse to compile * with a gcc that is known to be too old from the very beginning. */ -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95) +#if __GNUC__ < 3 #error Sorry, your GCC is too old. It builds incorrect kernels. #endif diff -L include/linux/compiler-gcc2.h -puN include/linux/compiler-gcc2.h~abandon-gcc-295x /dev/null --- devel/include/linux/compiler-gcc2.h +++ /dev/null 2003-09-15 06:40:47.000000000 -0700 @@ -1,29 +0,0 @@ -/* Never include this file directly. Include <linux/compiler.h> instead. */ - -/* These definitions are for GCC v2.x. */ - -/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented - a mechanism by which the user can annotate likely branch directions and - expect the blocks to be reordered appropriately. Define __builtin_expect - to nothing for earlier compilers. */ -#include <linux/compiler-gcc.h> - -#if __GNUC_MINOR__ < 96 -# define __builtin_expect(x, expected_value) (x) -#endif - -#define __attribute_used__ __attribute__((__unused__)) - -/* - * The attribute `pure' is not implemented in GCC versions earlier - * than 2.96. - */ -#if __GNUC_MINOR__ >= 96 -# define __attribute_pure__ __attribute__((pure)) -# define __attribute_const__ __attribute__((__const__)) -#endif - -/* GCC 2.95.x/2.96 recognize __va_copy, but not va_copy. Actually later GCC's - * define both va_copy and __va_copy, but the latter may go away, so limit this - * to this header */ -#define va_copy __va_copy diff -puN include/linux/compiler.h~abandon-gcc-295x include/linux/compiler.h --- devel/include/linux/compiler.h~abandon-gcc-295x 2005-12-13 00:48:17.000000000 -0800 +++ devel-akpm/include/linux/compiler.h 2005-12-13 00:48:17.000000000 -0800 @@ -42,8 +42,6 @@ extern void __chk_io_ptr(void __iomem *) # include <linux/compiler-gcc4.h> #elif __GNUC__ == 3 # include <linux/compiler-gcc3.h> -#elif __GNUC__ == 2 -# include <linux/compiler-gcc2.h> #else # error Sorry, your compiler is too old/not recognized. #endif _
From: Andrew Morton [email blocked] Subject: Re: [PATCH 1/19] MUTEX: Introduce simple mutex implementation Date: Tue, 13 Dec 2005 01:02:33 -0800 Andrew Morton [email blocked] wrote: > > Thus far I have this: > And this: From: Andrew Morton[email blocked] Remove various things which were checking for gcc-1.x and gcc-2.x compilers. Signed-off-by: Andrew Morton [email blocked] --- arch/arm/kernel/asm-offsets.c | 7 +------ arch/arm26/kernel/asm-offsets.c | 7 ------- arch/ia64/kernel/head.S | 2 +- arch/ia64/kernel/ia64_ksyms.c | 2 +- arch/ia64/oprofile/backtrace.c | 2 +- drivers/md/raid0.c | 6 ------ fs/xfs/xfs_log.h | 8 +------- include/asm-um/rwsem.h | 4 ---- include/asm-v850/unistd.h | 18 ------------------ include/linux/seccomp.h | 6 +----- include/linux/spinlock_types_up.h | 14 -------------- 11 files changed, 6 insertions(+), 70 deletions(-) diff -puN drivers/md/raid0.c~remove-gcc2-checks drivers/md/raid0.c --- devel/drivers/md/raid0.c~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800 +++ devel-akpm/drivers/md/raid0.c 2005-12-13 00:51:35.000000000 -0800 @@ -307,9 +307,6 @@ static int raid0_run (mddev_t *mddev) printk("raid0 : conf->hash_spacing is %llu blocks.\n", (unsigned long long)conf->hash_spacing); { -#if __GNUC__ < 3 - volatile -#endif sector_t s = mddev->array_size; sector_t space = conf->hash_spacing; int round; @@ -440,9 +437,6 @@ static int raid0_make_request (request_q { -#if __GNUC__ < 3 - volatile -#endif sector_t x = block >> conf->preshift; sector_div(x, (u32)conf->hash_spacing); zone = conf->hash_table[x]; diff -puN fs/xfs/xfs_log.h~remove-gcc2-checks fs/xfs/xfs_log.h --- devel/fs/xfs/xfs_log.h~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800 +++ devel-akpm/fs/xfs/xfs_log.h 2005-12-13 00:52:10.000000000 -0800 @@ -30,13 +30,7 @@ * By comparing each compnent, we don't have to worry about extra * endian issues in treating two 32 bit numbers as one 64 bit number */ -static -#if defined(__GNUC__) && (__GNUC__ == 2) && ( (__GNUC_MINOR__ == 95) || (__GNUC_MINOR__ == 96)) -__attribute__((unused)) /* gcc 2.95, 2.96 miscompile this when inlined */ -#else -__inline__ -#endif -xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) +static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2) { if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2)) return (CYCLE_LSN(lsn1)<CYCLE_LSN(lsn2))? -999 : 999; diff -puN arch/arm/kernel/asm-offsets.c~remove-gcc2-checks arch/arm/kernel/asm-offsets.c --- devel/arch/arm/kernel/asm-offsets.c~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800 +++ devel-akpm/arch/arm/kernel/asm-offsets.c 2005-12-13 00:53:27.000000000 -0800 @@ -23,18 +23,13 @@ #error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32 #endif /* - * GCC 2.95.1, 2.95.2: ignores register clobber list in asm(). * GCC 3.0, 3.1: general bad code generation. * GCC 3.2.0: incorrect function argument offset calculation. * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c * (http://gcc.gnu.org/PR8896) and incorrect structure * initialisation in fs/jffs2/erase.c */ -#if __GNUC__ < 2 || \ - (__GNUC__ == 2 && __GNUC_MINOR__ < 95) || \ - (__GNUC__ == 2 && __GNUC_MINOR__ == 95 && __GNUC_PATCHLEVEL__ != 0 && \ - __GNUC_PATCHLEVEL__ < 3) || \ - (__GNUC__ == 3 && __GNUC_MINOR__ < 3) +#if __GNUC__ < 2 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) #error Your compiler is too buggy; it is known to miscompile kernels. #error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3 #endif diff -puN arch/arm26/kernel/asm-offsets.c~remove-gcc2-checks arch/arm26/kernel/asm-offsets.c --- devel/arch/arm26/kernel/asm-offsets.c~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800 +++ devel-akpm/arch/arm26/kernel/asm-offsets.c 2005-12-13 00:53:47.000000000 -0800 @@ -25,13 +25,6 @@ #if defined(__APCS_32__) && defined(CONFIG_CPU_26) #error Sorry, your compiler targets APCS-32 but this kernel requires APCS-26 #endif -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95) -#error Sorry, your compiler is known to miscompile kernels. Only use gcc 2.95.3 and later. -#endif -#if __GNUC__ == 2 && __GNUC_MINOR__ == 95 -/* shame we can't detect the .1 or .2 releases */ -#warning GCC 2.95.2 and earlier miscompiles kernels. -#endif /* Use marker if you need to separate the values later */ diff -puN arch/ia64/kernel/ia64_ksyms.c~remove-gcc2-checks arch/ia64/kernel/ia64_ksyms.c --- devel/arch/ia64/kernel/ia64_ksyms.c~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800 +++ devel-akpm/arch/ia64/kernel/ia64_ksyms.c 2005-12-13 00:54:02.000000000 -0800 @@ -103,7 +103,7 @@ EXPORT_SYMBOL(unw_init_running); #ifdef ASM_SUPPORTED # ifdef CONFIG_SMP -# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) +# if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) /* * This is not a normal routine and we don't want a function descriptor for it, so we use * a fake declaration here. diff -puN arch/ia64/kernel/head.S~remove-gcc2-checks arch/ia64/kernel/head.S --- devel/arch/ia64/kernel/head.S~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800 +++ devel-akpm/arch/ia64/kernel/head.S 2005-12-13 00:54:10.000000000 -0800 @@ -1060,7 +1060,7 @@ SET_REG(b5); * the clobber lists for spin_lock() in include/asm-ia64/spinlock.h. */ -#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) +#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) GLOBAL_ENTRY(ia64_spinlock_contention_pre3_4) .prologue diff -puN arch/ia64/oprofile/backtrace.c~remove-gcc2-checks arch/ia64/oprofile/backtrace.c --- devel/arch/ia64/oprofile/backtrace.c~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800 +++ devel-akpm/arch/ia64/oprofile/backtrace.c 2005-12-13 00:54:16.000000000 -0800 @@ -32,7 +32,7 @@ typedef struct u64 *prev_pfs_loc; /* state for WAR for old spinlock ool code */ } ia64_backtrace_t; -#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) +#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) /* * Returns non-zero if the PC is in the spinlock contention out-of-line code * with non-standard calling sequence (on older compilers). diff -puN include/linux/spinlock_types_up.h~remove-gcc2-checks include/linux/spinlock_types_up.h --- devel/include/linux/spinlock_types_up.h~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800 +++ devel-akpm/include/linux/spinlock_types_up.h 2005-12-13 00:55:14.000000000 -0800 @@ -22,30 +22,16 @@ typedef struct { #else -/* - * All gcc 2.95 versions and early versions of 2.96 have a nasty bug - * with empty initializers. - */ -#if (__GNUC__ > 2) typedef struct { } raw_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { } -#else -typedef struct { int gcc_is_buggy; } raw_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED (raw_spinlock_t) { 0 } -#endif #endif -#if (__GNUC__ > 2) typedef struct { /* no debug version on UP */ } raw_rwlock_t; #define __RAW_RW_LOCK_UNLOCKED { } -#else -typedef struct { int gcc_is_buggy; } raw_rwlock_t; -#define __RAW_RW_LOCK_UNLOCKED (raw_rwlock_t) { 0 } -#endif #endif /* __LINUX_SPINLOCK_TYPES_UP_H */ diff -puN include/linux/seccomp.h~remove-gcc2-checks include/linux/seccomp.h --- devel/include/linux/seccomp.h~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800 +++ devel-akpm/include/linux/seccomp.h 2005-12-13 00:55:25.000000000 -0800 @@ -26,11 +26,7 @@ static inline int has_secure_computing(s #else /* CONFIG_SECCOMP */ -#if (__GNUC__ > 2) - typedef struct { } seccomp_t; -#else - typedef struct { int gcc_is_buggy; } seccomp_t; -#endif +typedef struct { } seccomp_t; #define secure_computing(x) do { } while (0) /* static inline to preserve typechecking */ diff -puN include/asm-um/rwsem.h~remove-gcc2-checks include/asm-um/rwsem.h --- devel/include/asm-um/rwsem.h~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800 +++ devel-akpm/include/asm-um/rwsem.h 2005-12-13 00:55:41.000000000 -0800 @@ -1,10 +1,6 @@ #ifndef __UM_RWSEM_H__ #define __UM_RWSEM_H__ -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) -#define __builtin_expect(exp,c) (exp) -#endif - #include "asm/arch/rwsem.h" #endif diff -puN include/asm-v850/unistd.h~remove-gcc2-checks include/asm-v850/unistd.h --- devel/include/asm-v850/unistd.h~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800 +++ devel-akpm/include/asm-v850/unistd.h 2005-12-13 00:56:07.000000000 -0800 @@ -241,9 +241,6 @@ /* User programs sometimes end up including this header file (indirectly, via uClibc header files), so I'm a bit nervous just including <linux/compiler.h>. */ -#if !defined(__builtin_expect) && __GNUC__ == 2 && __GNUC_MINOR__ < 96 -#define __builtin_expect(x, expected_value) (x) -#endif #define __syscall_return(type, res) \ do { \ @@ -346,20 +343,6 @@ type name (atype a, btype b, ctype c, dt __syscall_return (type, __ret); \ } -#if __GNUC__ < 3 -/* In older versions of gcc, `asm' statements with more than 10 - input/output arguments produce a fatal error. To work around this - problem, we use two versions, one for gcc-3.x and one for earlier - versions of gcc (the `earlier gcc' version doesn't work with gcc-3.x - because gcc-3.x doesn't allow clobbers to also be input arguments). */ -#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f) \ - __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \ - : "=r" (ret), "=r" (syscall) \ - : "1" (syscall), \ - "r" (a), "r" (b), "r" (c), "r" (d), \ - "r" (e), "r" (f) \ - : SYSCALL_CLOBBERS, SYSCALL_ARG4, SYSCALL_ARG5); -#else /* __GNUC__ >= 3 */ #define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f) \ __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \ : "=r" (ret), "=r" (syscall), \ @@ -368,7 +351,6 @@ type name (atype a, btype b, ctype c, dt "r" (a), "r" (b), "r" (c), "r" (d), \ "2" (e), "3" (f) \ : SYSCALL_CLOBBERS); -#endif #define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \ type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \ _
From: Linus Torvalds [email blocked] To: Andi Kleen [email blocked] Subject: Re: [PATCH 1/19] MUTEX: Introduce simple mutex implementation Date: Tue, 13 Dec 2005 08:16:39 -0800 (PST) On Tue, 13 Dec 2005, Andi Kleen wrote: > > Remove -Wdeclaration-after-statement Please don't. It's a coding style issue. We put our variable declarations where people can _find_ them, not in random places in the code. Putting variables in the middle of code only improves readability when you have messy code. Now, one feature that _may_ be worth it is the loop counter thing: for (int i = 10; i; i--) ... kind of syntax actually makes sense and is a real feature (it makes "i" local to the loop, and can actually help people avoid bugs - you can't use "i" by mistake after the loop). But I think you need "--std=c99" for gcc to take that. Linus
From: Andrew Morton [email blocked] Subject: Re: [PATCH 1/19] MUTEX: Introduce simple mutex implementation Date: Tue, 13 Dec 2005 01:15:40 -0800 Andi Kleen [email blocked] wrote: > > On Tue, Dec 13, 2005 at 01:01:26AM -0800, Andrew Morton wrote: > > Andi Kleen [email blocked] wrote: > > > > > > Can you please apply the following patch then? > > > > > > Remove -Wdeclaration-after-statement > > > > OK. > > > > Thus far I have this: > > Would it be possible to drop support for gcc 3.0 too? Spose so - I don't know what people are using out there. > AFAIK it has never been widely used. If we assume 3.1+ minimum it has the > advantage that named assembly arguments work, which make > the inline assembly often a lot easier to read and maintain. There are a few places in the tree which refuse to compile with 3.1 and 3.2.
From: Andi Kleen [email blocked] Subject: Re: [PATCH 1/19] MUTEX: Introduce simple mutex implementation Date: Tue, 13 Dec 2005 10:24:37 +0100 > Spose so - I don't know what people are using out there. I don't think it was shipped in major distros at least (AFAIK) They all went from 2.95 to 3.1/3.2 Perhaps stick an error for 3.0 in and wait if people are complaining? > > > AFAIK it has never been widely used. If we assume 3.1+ minimum it has the > > advantage that named assembly arguments work, which make > > the inline assembly often a lot easier to read and maintain. > > There are a few places in the tree which refuse to compile with 3.1 and 3.2. Really? Which ones? Haven't seen that and I still use 3.2 occasionally (it's the default compiler on SLES9 and I believe on RHEL3 too) -Andi
From: Andrew Morton [email blocked] Subject: Re: [PATCH 1/19] MUTEX: Introduce simple mutex implementation Date: Tue, 13 Dec 2005 01:44:37 -0800 Andi Kleen [email blocked] wrote: > > > There are a few places in the tree which refuse to compile with 3.1 and 3.2. > > Really? Which ones? grep for __GNUC_MINOR__
From: Andi Kleen [email blocked] Subject: Re: [PATCH 1/19] MUTEX: Introduce simple mutex implementation Date: Tue, 13 Dec 2005 10:49:33 +0100 On Tue, Dec 13, 2005 at 01:44:37AM -0800, Andrew Morton wrote: > Andi Kleen [email blocked] wrote: > > > > > There are a few places in the tree which refuse to compile with 3.1 and 3.2. > > > > Really? Which ones? > > grep for __GNUC_MINOR__ I reviewed them and I didn't find any that refused 3.2 or 3.3. Some architectures have special code for old gccs, but nothing generic. -Andi



Related Links:

Why do people keep adding ano

December 13, 2005 - 9:46pm
Anonymous (not verified)

Why do people keep adding anonymous unions to Linux? Why don't the Linux maintainers just unanomize them by giving them names? Doesn't Linux have coding standards? and compile with all warnings enabled?

Anonymous unions are useful -

December 13, 2005 - 10:38pm
E (not verified)

Anonymous unions are useful - that's why they are there.

Asking why Linux maintainers dont "unanonymize" warnings shows a certain lack of understanding of the Linux dev processes. The sheer size of the project means that instead of individual patch review, major projects (like the TCP/IP stack, or the IDE subsystem) simply push major code drops upstream. Andrew can't be doing a line by line review of the code - he has to trust those who push things to him, and Linus trusts Andrew . . .

Linux does have coding standards - the code has to be good. It doesn't have to meet a certain number of arbitrary rules about what features can and cannot be used. A project as sophisticated and complex as the Linux kernel doesn't run that way. This isn't a single house project, where everyone reports to the same guy twice a month for a paycheck.

As for compiling with warnings enabled, the sheer variety of compiler targets the kernel supports, plus the complex hoops that the kernel has to jump through makes that impossible: for example, drivers often read from memory mapped hardware registers: which to the compiler looks like reading from uninitialized memory.

Andrew can't be doing a line

December 14, 2005 - 12:37am
Anonymous (not verified)

Andrew can't be doing a line by line review of the code - he has to trust those who push things to him, and Linus trusts Andrew . . .

This is a major cop out. Obviously Andrew can't review every patch line-by-line. No kidding. But that doesn't mean standards can't be enforced. State the standard, state the consequences for those who violate it. Enforce them whenever a violation is found. Voila.

Linux does have coding standards - the code has to be good. It doesn't have to meet a certain number of arbitrary rules about what features can and cannot be used.

Yes, it does have to be good. Part of being "good" means actually building under the full range of compilers the kernel theoretically supports. Feature rules, as determined by the supported range of compiler versions, are not arbitrary.

As for compiling with warnings enabled, the sheer variety of compiler targets the kernel supports, plus the complex hoops that the kernel has to jump through makes that impossible...

I disagree, conditionally. Doesn't gcc support disabling specific warnings via pragmas?

But that doesn't mean standar

December 15, 2005 - 6:23pm
Anonymous (not verified)

But that doesn't mean standards can't be enforced.

Well they do that. But the standards are subject to change. Not everybody wants to stay in the dark ages. If anonymous unions are useful, then why not use them?

>> If anonymous unions are us

December 17, 2005 - 1:44pm
Anonymous (not verified)

>> If anonymous unions are useful, then why not use them?
Other than allowing developers to be too lazy to give the union a name, what use does anonymous unions have?

Clarity more than laziness.

December 19, 2005 - 5:17pm

It does make the code much easier to read, IMHO. For instance, in one my parsers, I use a union to capture multiple data types and I have a tag field that says which type is valid. I happened to call that union "what". So, getting to various types becomes "token->what.text" or "token->what.value" or "token->what.id". It's much more convenient and quite a bit clearer to just say "token->text" or "token->value" or "token->id". In most cases, the type I'm after is guaranteed by context, so the additional visual clutter of referencing the union explicitly adds nothing to this. The situation gets more absurd when you union various structs together. Now you have *three* levels of namespace to traverse instead of two.

This aspect of nested unions and the "with/do" clause are two features of standard Pascal that I really miss in standard C. I only sorta miss nested functions. Both lead to clearer code, IMHO, by getting rid of mind-numbingly redundant text leaving you to see exactly what's going on.

Overall, this is the same principle behind naming loop counters i, j and k, rather than "first_index_counter_variable," "second_index_counter_variable," "third_index_counter_variable."

"As for compiling with warnin

December 14, 2005 - 4:48am
tu (not verified)

"As for compiling with warnings enabled, the sheer variety of compiler targets the kernel supports, plus the complex hoops that the kernel has to jump through makes that impossible: for example, drivers often read from memory mapped hardware registers: which to the compiler looks like reading from uninitialized memory."

har.
1. variety of targets has nothing to do with it. in fact, you want more warnings so you don't get screwed by broken code that works sometimes.
2. complex hoops my ass. i'm running a kernel compiled with -Wall -Werror (but it's not linux, that's for sure).
3. you've obviously never looked at a driver; a memory mapped register looks *nothing* like uninitialized memory.

The newer 2.6 kernels compile

December 14, 2005 - 1:35pm

The newer 2.6 kernels compiled without warnings for me with gcc 3.4, except a few "X is deprecated" ones. When switching to gcc 4.0 there came a lot of variable may be uninitialized when used kind of warnings, but I checked the code and it just couldn't really happen. So it seems like gcc 4.0 is a bit too eager to warn about certain things, which will hopefully be fixed in newer versions.

Not all warnings make sense

December 14, 2005 - 1:47pm

First of all, as far as -Wall is considered "all warnings" Linux *is* comiled with all warnings enabled. But in fact, -Wall doesn't enable *all* warnings and the Linux kernel Makefile actually enable a few in addition to what -Wall enables.
If you take a look at the Makefile you'll see :

HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \
-ffreestanding

Yet more warnings could be enabled, one could for example use something like

-W -Wall -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion -Waggregate-return -Wstrict-prototypes -Wpadded -Winline

but the result would be a flood of completely pointless warnings about things that are perfectly OK.
Not all warnings make sense in all situations and cleaning up such pointless warnings often just leads to code that's harder to read or less efficient or both - and the generated code is usually not at all "better".
Actually, you don't have to go overboard like I did above to see pointless warnings, just try building with just -W -Wall and you'll see loads of warnings that are completely irrelevant (and sometimes just plain wrong).

Actually, you don't have to g

December 14, 2005 - 2:02pm
Anonymous (not verified)

Actually, you don't have to go overboard like I did above to see pointless warnings, just try building with just -W -Wall and you'll see loads of warnings that are completely irrelevant (and sometimes just plain wrong).

Then just enable warnings during kernal compilation that have a "high probability" of catching code that is genuinely dangerous. This assumes that a set of "likely to catch real problems" warnings can actually be constructed. If not, then warnings are pretty much useless.

only use sensible warnings

December 14, 2005 - 3:52pm

Then just enable warnings during kernal compilation that have a "high probability" of catching code that is genuinely dangerous.

Which is exactely what's done.

Actually, I don't know what all the fuzz is about. This really is a case of "nothing to see here, move along...".

This assumes that a set of "likely to catch real problems" warnings can actually be constructed. If not, then warnings are pretty much useless.

HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \
-ffreestanding

Which is what the kernel uses comes pretty close to being that set of "these make sense" warnings...

It's FUD

December 15, 2005 - 3:57pm
Anonymous (not verified)

These are BSD or solaris zealots posting here to try to discredit linux and the way it is developed.

That's why Linux rocks - they

December 15, 2005 - 6:11pm
Anonymous (not verified)

That's why Linux rocks - they don't give rats ass about wrong warnings.
Nothing worse than code-fascists.

Nothing worse than code-fasci

December 15, 2005 - 7:56pm
Anonymous (not verified)

Nothing worse than code-fascists.

Sure there is. Sloppy developers.

You've got a point there. Bu

December 16, 2005 - 11:43am
Anonymous (not verified)

You've got a point there.
But the warnings in the kernel aren't necessarily sloppy code. There's a rule not to add silly/buggy code constructs to shut up bogus warnings. Actually many of the fix-some-warnings kind of patches are rejected for that reason.

Coding standards on warnings

December 23, 2005 - 9:34am
Wol (not verified)

Which was why our corporate standard (which I set) was

"set warning level to maximum. Get rid of or explain away all warnings".

We still had loads of warnings, but at least we knew why ...

Cheers,
Wol

hm?

December 15, 2005 - 1:50pm
Anonymous23 (not verified)

"drivers often read from memory mapped hardware registers: which to the compiler looks like reading from uninitialized memory."

That's just another reason to declare such memory areas "volatile", so the compiler doesn't attempt to make any assumptions at all about its contents.

Drivers shouldn't read direct

December 16, 2005 - 8:48am

Drivers shouldn't read directly from memory mapped hardware registers, but use the appropriate access functions for that. So if you see actual drivers doing that, then report that or fix them.

>> for example, drivers often

December 17, 2005 - 2:12pm
Anonymous (not verified)

>> for example, drivers often read from memory mapped hardware registers: which to the compiler looks like reading from uninitialized memory.

There's a reason why you are supposed to use ioremap, in*, out*, write*, read* functions/macros.

And actually, I don't know what warning flag you are using to get those warnings... I can compile the following code with 'gcc -Wall -Wuninitialized -O test.c' with no warnings:

int main(){
char * c = (char *)124;
*c = 2;
*((char *) 355) = 3;
*c = *((char *)81);
return 42;
}

It looks like gcc only cares about variables on the stack thare aren't initialized, it doesn't care about pointers to registers.... and if you are somehow using a local variable that has the same memory address as a device register, I'd like to know how/why. I've only done one driver, so I could be missing out on some voodoo in the MMU code or something

No one seems to relize that d

December 14, 2005 - 7:56pm
Anonymous (not verified)

No one seems to relize that developer time is needed to check that all patchs work with all compilers, so the fewer compilers that linux supports the less workt there is to do. Frankly it is time to move on from 2.95.

fix 2.95?

December 15, 2005 - 1:20pm

How hard would it be to write a patch to 2.95 so the kernel compiles correctly (or at least so it doesn't ICE)? Then we could have gcc 2.95.5.

Also I hope this is just in new work that 2.95 support is dropping for; it would be terrible to see the 2.4 kernel not build on 2.95.

No point

December 15, 2005 - 8:03pm

2.95 is the officially supported gcc for 2.4 so that will never be dropped. Fixing 2.95 is pointless as it will start turning into gcc3 basically as more and more new features need to be supported.

There isn't really much to do

December 16, 2005 - 12:39pm
Anonymous (not verified)

There isn't really much to do. And as long as gcc 3.x has the feature of being slow-as-shit, people are gonna want to stick with it.

Buy better hardware?

December 16, 2005 - 1:48pm
Alolymous (not verified)

Buy better hardware? Seriously, you'd think these devs were stuck on vintage 1991 386s the way they complain.

Not devs

December 17, 2005 - 12:04am

Very few of the kernel devs themselves are complaining. I can only imagine discontinued slower hardware that is still supported (eg sparc32) would really be significantly affected. As for compilation speed, features usually cost you speed (I know it's not universal).

GCC 2.95.3 released: March 16, 2001

Really it's time to move on for 2.6. Andrew Morton is right; time is limited and supporting older gccs wastes developer time and does not benefit the kernel itself.

Yeah, it's time.

December 19, 2005 - 5:15pm

You know you've been using Linux awhile when you remember when they warned people off of GCC 2.3.x... ...and you remember reading about their brief experiment compiling it as a C++ application.

The C++ experiment happened around 0.99.10. The first kernel I compiled, 0.99.13, already had that disabled:

CFLAGS = -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer # -x c++

I never ran 0.99.10, but I did run 0.99.7 while installing SLS 1.03. Am I officially a Linux old fart now?

That may be, but people who d

December 19, 2005 - 10:28pm
Anonymous (not verified)

That may be, but people who depend on compilation speed are still going to want to stick with gcc 2.95. I'm not about to go tell the QA dept. to switch to gcc 3.slow and have all the auto-regression & test machines take 2 days instead of one.

2 days instead of one

December 29, 2005 - 6:20am
Anonymous (not verified)

If all your QA dept. does is compiling code, maybe it would take "2 days" (which is bullshit, gcc 3.slow is not _that_ slow). But you are testing a compiled kernel, not a compiler. Once your kernel is built, testing it will not suddenly take more time, just because it was compiled with gcc3. In fact gcc3.[34] produce far better code than gcc 2.95.stoneage, you may even find that the time to test everything doesn't change at all.

Depends on what you're QAing.

December 31, 2005 - 6:50pm

If you're QAing a kernel build, chances are the generated code quality is of miniscule importance. In fact, anything with significant I/O will be largely bottlenecked by the hard drive, not the compiled code.

FWIW, I am currently attempting to run some benchmarks compiling the 2.4.18 kernel with both GCC 2.96 and GCC 3.4.5. (GCC 2.96 and Linux 2.4.18 because it's an old RH 7.2 machine with not much disk space, and those are already on there.)

Just a followup.

January 2, 2006 - 1:39am

I ended up performing my experiment with a more recent kernel. Turns out the 2.4.18-3 kernel that came with this ancient RedHat won't build with modern GCC. So, I grabbed the 2.6.14 kernel instead.

As you can see below, GCC 2.96 was over 10% slower than GCC 3.4.5. I'm willing to call the GCC 3.slow argument a red herring in the absence of other data to the contrary. I think some people tried GCC 3.0.x or maybe 3.1.x to 3.2.x, got a bad impression, and haven't been back recently.

(For those too lazy to scroll down... 2.96 took about 198 minutes, as compared to 3.4.5, which took just shy of 179 minutes.)

Ok, post a benchmark.

December 20, 2005 - 2:40pm

I know the early 3.x compilers left a bad taste in people's mouths speed-wise, but later compilers sped things up. How long really does it take to build a kernel from scratch with each?

Post some real numbers. I ain't going to cry for 20%. If it's 2x off, let's work on fixing GCC, eh?

Ok, a benchmark. Now quit yer b****ing.

January 2, 2006 - 1:31am

Ok, I took the 2.6.14 kernel and compiled bzImage twice on a Pentium 60. I did it once with GCC 2.96 and once with GCC 3.4.5, and I timed them both.

For each, I did "make clean" and "make oldconfig" outside of the timing. Then I timed simply "make bzImage." In a separate console I had a "vmstat 10" to keep an eye on the CPU and swap.

The machine has only 32MB RAM. Swapping wasn't a problem, though. At the start of the tests, I had about 2.6MB in swap. The peak swap usage during GCC 2.96 was about 4.4MB, and the peak during 3.4.5 was 3.8MB. (IIRC... I didn't record the vmstat to a file.)

Building 2.6.14 with 2.96 took 198m18.063s according to "time." Building 2.6.14 with 3.4.5 took 178m58.377s.

I realize 2.96 isn't 2.95.3. It's an earlier 2.95 that was patched by RedHat so it'd build valid kernels. But still, the fact that 2.96 was over 10% slower on a CPU-bound machine than 3.4.5 should count for something.

3.0.x sucked. I'll give you that any day of the week. 3.1 and 3.2 worked to establish the former glory. 3.4 obviously has made up for past sins. Either that, or there's something magic about the Pentium 1 that rewards 3.4.5 and penalizes 2.96.

Unless someone posts a convincing benchmark to the contrary, I'm going to label "3.slow" a red herring.

2.96 _WAS NOT_ an earlier 2.9

January 4, 2006 - 12:49pm
mu (not verified)

2.96 _WAS NOT_ an earlier 2.95. It was pre-realease of 3.0.

Redhat distributed this release with redhat 7 in order to get STL support out the door.

2.95 and 2.96 are from different code bases. 2.96 is from the egcs project, which is the current base for 3.x/4.x. 2.95 is the last of the old gcc code.

There was a fork at some point, but i don't recall the details.
--
Mu

I found that out.

January 6, 2006 - 11:44am

Yes, I figured that out. Actually, I redid my benchmark (and posted about it on a different thread here on KernelTrap) using 2.95.3. I should've posted that here also. Here's what I posted elsewhere on KernelTrap:

A retraction is in order.
Comment posted by Mr_Z on Tuesday, January 3, 2006 - 21:02

I was so surprised myself by the GCC 2.96 results that I wondered if 2.96 was the minimal delta I claimed it to be. Looking through Andrew Morton's patch to remove 2.95 support hinted it might be closer to 3.0 than 2.95. Sure enough, the benchmark numbers seem to agree.

GCC 2.95.3:

real    120m43.057s
user    110m54.690s
sys     7m57.820s

So, GCC 3.4.5 is about 12% faster than 2.96, and about 47% slower than 2.95.3.

Taking about 50% longer is pretty noticeable. With this only quasi-scientific analysis, it seems GCC 3.x does deserve, at least somewhat, the moniker GCC 3.slow. Granted, on a faster machine, the difference should narrow. (Other factors of the build such as disk access speed make more difference if you're less CPU bound.) And on a machine with more RAM it should narrow further with "make -j2 bzImage," but nonetheless there *is* a large compilation time delta here.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
speck-geostationary