GCC 4.6.0 — Tinderbox results so far

So, thanks to Ryan, support for GCC 4.6.0 in Gentoo is working fast: the ebuild for this new version entered the tree last week, and the GCC porting team already prepared an overlay with at least a bunch of ebuilds fixed to build with this new version. To speed up the process, I made sure to set off my tinderbox – which by the way is in dire need of more RAM, see the link – to test packages for compatibility.

Most of the issues with this new version have been already documented, for instance, in a Fedora devel post and spending too much time writing about the detailed error cases is a waste of time and words for what I’m concerned. If I want to make an useful post – and I want – I should find something that is not already covered there; so instead of documenting the errors themselves, I’d like to give a general overview of the situations that I found with the tinderbox, especially those that were mostly unexpected — most of which relate to configure scripts written with autoconf.

The most interesting situation is caused by the new -Wunused-but-set-variable warning, which actually makes me quite happy, since I complained the lack of that particular warning back in 2008! As usual with any new warning introduced, software wrongly building with @-Werror@ will fail – another thing I ranted about in 2009 – and unfortunately there are still packages in Gentoo, old and newly-introduced, using -Werrorfor building by default, sigh)

But more importantly, there is one use of -Werror that is usually accepted as proper: using it to write Autoconf checks so that they don’t provide false positives if the compiler accepts slightly-wrong results. For instance, most compilers would only produce a warning if an unknown attribute is encountered, or if an attribute is declared in the wrong position. By adding -Werror (or its equivalent options for other compilers), it is much easier to identify if it supports a given syntax, or if a function has one given set of parameters. In this situation, adding a new warning can be quite a nuisance, because the source of the test that worked with one compiler version would cause the next one to fail.

Again, this is something well-known and expected to behave this way, so why am I focusing so much on it? Well, the problem is that a combination of two recent developments seem to cause heavier headaches. With GCC 4.5 and a recent GLIBC version, a number of functions emit a warning if their result value is ignored; to shut up such warnings, rather than properly handling the function’s return value, sloppy developers simply added a new variable to store the return value, but never checked it again. Do I have to remind you what -Wunused-but-set-variable warns you about? Yes, exactly that situation.

/* this causes a warning in GCC 4.5 and recent GLIBC */
int foo(const char *dir) {
  /* ... */
  chdir(dir);
}

/* and was often enough replaced with this, which causes a warning with GCC 4.6 */
int foo(const char *dir) {
  int res;
  /* ... */
  res = chdir(dir);
}

Unfortunately, when this happens within configure tests, it is quite a bit of problem, since most of the tests structured that way that their failure wouldn’t cause a build failure, but would rather consider features and interfaces as “not supported”. While probably most of the time this is unlikely to make huge difference for the user – attributes for instance are generally used to increase the SNR but produce no runtime difference – it might very well be that optional safety measures or optimisations are ignored because some feature is identified as “unsupported”; if it’s not a whole feature that is then missing.

Tracking down these issues downstream, either through distributions or users, doesn’t seem feasible to me; probably a number of these will hide for the months to come until somebody looks at the configure script minutely. For those interested in checking out if there are any differences at all between two ./configure run with GCC 4.6 or 4.6, I have a personal method. Assume you have a system with both slots of GCC installed, with gcc referring to the selected 4.5, while the 4.6 branch available as gcc-4.6.0, a project based on autotools, such as feng and you wish to see that the results correspond. In such a case, follow my example here (the runconfigure script is used to pass a series of default arguments to ./configure and is the same between the two calls):

flame@yamato feng % cd yamato
flame@yamato yamato % ./runconfigure &> config.out
flame@yamato yamato % cd ../yamato-gcc46 
flame@yamato yamato-gcc46 % ./runconfigure &> config.out
flame@yamato feng % sed -i -e 's:gcc-4.6.0:gcc:' config.out
flame@yamato feng % diff -u yamato*/config.out

The sed call is needed to avoid that tests showing the compiler name are reported as differing; both libtool and my own custom macro tests do that, and I’m not sure if it’s a good thing, given this requirement. And thinking about this right now I wonder if it isn’t wrong also when running the tests for the C++ compiler rather than the C one.

The next important thing to note relates to GCC now bailing out on a number of parameters that it ignored before and that were mistakenly passed to the compiler frontend rather than to their own rightful handlers (libtool or ld). For instance, the compiler now refuses to accept link editor flags passed without the required -Wl, prefix, such as --as-needed or those that are meant for the libtool wrapper script, such as -export-dynamic; but the most interesting part is probably the -R flag.

The -R flag is accepted by both libtool and ld and is used to indicate to the link editor that it should append the path following it to the the rpath property on the produced ELF file. The gcc frontend used to deal with the flag itself, but this has also been dropped. Unfortunately, this flag is often used as a complement to the -L flag that appends the path following it to the list of library search paths of the link editor. Why do I say this is unfortunate? Well, the -L flag is also implemented in libtool and ld … but is also implemented directly by the gcc frontend; add the fact that the two options are usually used in pair, you can probably guess why this is tremendously confusing.

And all of this is yet without adding the new -Ofast flag to the mix — which I don’t think I’ll try, or that anybody should try it. Producing non-compliant code means risking that stuff relying on its compliance blow up, which would cause a number of false positives on tests, as well as making it unreliable to build other stuff over that. But more interesting than the compilation results would be checking the configuration scripts and build systems, as a number of them assume that -O only can be followed by a single digit, sometimes even just in the 0-3 range.

At the end, I’m going to crunch packages for the next few weeks finding more packages failing, that requires to be fixed. Luckily most of the problems seem to be only related to the missing inclusion of <cstddef> header in C++ software. As usual, I seriously think that a language that is still that much in flux between one compiler version and the other, decades after it was designed, is not something I’d wish to rely on for system software packages — and it makes me sad to see so many new applications relying heavily on it. But that’s personal opinion, of course.

Exit mobile version