Stupid GCC
Apr. 27th, 2009 02:49 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
$ cat t.c #include <stdio.h> int main(void) { return printf(""); } $ gcc -Wall -c t.c t.c: In function ‘main’: t.c:2: warning: zero-length printf format string $ gcc -Wall -Wno-format-zero-length -c t.c $ gcc --version gcc (Debian 4.3.2-1.1) 4.3.2 Copyright (C) 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Can anyone offer a plausible reason why:
- -Wformat-zero-length is on by default (i.e. implied by -Wformat and thus by -Wall)?
- Why it exists at all?
FTAOD, empty format strings are perfectly legitimate (and the GCC Manual knows this).
(no subject)
Date: 2009-04-27 02:05 pm (UTC)(no subject)
Date: 2009-04-27 02:10 pm (UTC)(no subject)
Date: 2009-04-27 02:14 pm (UTC)That suggests you're using a non-literal format string, which is a different code smell. But if you aren't, why are you writing:
instead of
?
(no subject)
Date: 2009-04-27 02:16 pm (UTC)read_from_terminal("")
rather than going out of your way to have a secondread_from_terminal_without_prompt()
function.(no subject)
Date: 2009-04-27 02:19 pm (UTC)(no subject)
Date: 2009-04-27 02:21 pm (UTC)read_from_terminal("%.*s", 0, "-Wformat-zero-length please choke on a bucket of socks");
eta: second comment on this entry I've had to edit to fix a misplaced negative. Perhaps I shouldn't have got out of bed.
(no subject)
Date: 2009-04-27 02:25 pm (UTC)(no subject)
Date: 2009-04-27 03:03 pm (UTC)(no subject)
Date: 2009-04-27 03:06 pm (UTC)__attribute__((printf))
feature.(no subject)
Date: 2009-04-27 02:13 pm (UTC)(I've often thought that a lot of compiler warnings need a special case "unless it was generated by a macro", because the sorts of things that indicate a probable user error when they appear in handwritten code are often very similar to the sorts of things that are perfectly sensible preprocessor output.)
(no subject)
Date: 2009-04-27 02:24 pm (UTC)(no subject)
Date: 2009-04-27 02:33 pm (UTC)__I_meant_to_do_this(arbitrary C code)
sort of construction which would work equally well against any warning, with which you could then liberally pepper your complicated macro setups.(In a really ideal world it would also work equally well in any compiler, but the boat is well and truly missed on that one.)
(no subject)
Date: 2009-04-27 02:06 pm (UTC)At a guess it's there in the first place because somebody did it by mistake, thought "That should be a warning, nobody is likely to need to do that" and so they put it in.
It doesn't seem unreasonable to me given
(no subject)
Date: 2009-04-27 02:11 pm (UTC)(no subject)
Date: 2009-04-27 02:40 pm (UTC)In both cases, something which might be expected to have no effect has been coded. Actually, given that excess arguments could be used for their side effects, there might be an argument that an empty format string is even less useful than excess arguments whose evaluation does something useful.
Also, given the same argument about format strings wrapped in macros, one could end up with a sequence like
printf("%s %d", StrArg1, IntArg1, IntArg2, IntArg3);
printf("%s %d %d", StrArg1, IntArg1, IntArg2, IntArg3);
printf("%s: (%d, %d)", StrArg1, IntArg1, IntArg2, IntArg3);
etc. being produced, and being warned about becuase not all the arguments get used.
something which might be expected to have no effect has been coded
Date: 2009-04-27 03:49 pm (UTC)(no subject)
Date: 2009-04-27 02:11 pm (UTC)Would you say
if(foo);
{ bar(); }
should not be warned about, just because it's perfectly legitimate C code?
Why would you want to do a zero-length format string deliberately anyway?
(no subject)
Date: 2009-04-27 02:14 pm (UTC)Usually the things that merit warnings are those for which the compiler won't do what the user might reasonably have expected. if(a=b) generates a warning because the programmer probably might plausibly have expected comparison rather than assignment, for instance.
An empty format string will do exactly what the user expected, though. You don't enter "" expecting to get "Hello, world!" out.
(no subject)
Date: 2009-04-27 03:19 pm (UTC)(no subject)
Date: 2009-04-27 03:33 pm (UTC)When I'm designing languages these days I tend to make "a && b || c" actually illegal: && and || have the same priority but will each only associate with themselves.
(no subject)
Date: 2009-04-28 09:51 am (UTC)(no subject)
Date: 2009-04-27 03:34 pm (UTC)I assume you mean -Wparentheses - if not then I must have some other GCC 4.3 to you! However, that construction has generated a warning for quite some time now:
(no subject)
Date: 2009-04-27 04:17 pm (UTC)$ gcc -Wall -c wall.c
wall.c: In function ‘foo’:
wall.c:1: warning: suggest parentheses around && within ||
$ g++ -Wall -c wall.c
$
... well, that's helpful, isn't it.
G++ 4.3 and above appear to be much better about warnings in C++ code. Even our old version of boost from ~3 years ago is not accepted.
(no subject)
Date: 2009-04-27 04:28 pm (UTC)(no subject)
Date: 2009-04-27 05:18 pm (UTC)(no subject)
Date: 2009-04-27 06:30 pm (UTC)(no subject)
Date: 2009-04-27 07:57 pm (UTC)and also because "There are lots of other checks for useless formats (e.g., for using useless combinations of flag characters where one gets ignored)".
(no subject)
Date: 2012-03-13 02:22 pm (UTC)GCC bug
Date: 2012-04-04 05:04 pm (UTC)