I hate closed-minded people ...
Edit: to be fair to the GCC crew, it seems the guy who closed me the bug to the face was not very representative of'em. Thanks to them to their very good compilation suite btw !
a bit of history
I've been bitten today by a problem due to the fact that I use the gcc __attribute__((nonull(...))) as a hint in my C headers to say to the programmer that it's up to him to check if what it pass to my function is NULL, or not. I had written (erouneously) that bit of code:
/* in the .h */
__attribute__((nonnull(1)))
char *m_strrtrim(char *s);
/* in the .c */
char *m_strrtrim(char *s)
{
ssize_t len = s ? strlen(s) : 0;
while (len > 1 && isspace((unsigned char)s[len - 1]))
len--;
return s + len;
}
I've added the __attribute__((nonnull)) by mistake, and indeed sometimes used m_strrtrim on strings that I knew to be NULL. The point is, gcc is able to use the nonnull attribute to optimize code, and that's very legitimate. In my case, it optimized the s ? strlen(s) : 0 into strlen(s). And without surprise, it caused segfaults.
I had a hard time finding that bug, because I've never thought that it could come from the header. As it could not come from the m_strrtrim function, I've looked very hard for stack overwrite and so on in the caller, but even valgrind did not catched anything interesting (except an invalid read size of 1 in strlen). It's when (in order to see if it was a gcc optimization bug) I've generated the preprocessed source that I saw the damn prototype in the preprocessor output, and that was suddently obvious to me why it segfaulted.
the wishlist bug
Since it was quite an unusual problem, that can make you loose a lot of time, because the bug lies very far from where it's revealed, I've opened a wishlist bug in gcc to ask for a warning when you test some pointer against NULL that you should already know to be non-NULL. like the warning about always true (or always false) comparisons for e.g.:
size_t len;
// ...
if (len >= 0) { ... // always true
if (len < 0) { ... // always false
That's gcc bug#30043. Or I should say was. My bugreport has indeed be closed a first time as INVALID, because the reader thought I said the gcc optimization was not legitimate (*sigh*). I reopened it explaining more precisely that I only begged for a warning, not for anything else, and that YES I DID READ THE DOC.
The bug has just been closed as WONTFIX this time, with an explanation that still makes me stare at it with a blank look:
I don't think a warning is the right thing in this case because the developer should have read the documention […]
WTF !?
If reading the documentation can make you a perfect programmer that never do any mistake, then god, I must be a super-mega-coder that always write perfect code ! Sadly, reading the doc do not prevent you to avoid cuts (aka segfaults) when you juggle with razorblades (aka code in C).
I can understand that it's hard to do in the present state of GCC, and that's it's not an urgent feature, given how peculiar that request is. But I'm completely stunned to see that a guy that is in the compiler business just consider that a warning is useless, and that the documentation is the key answer. I use an over-long compilation line in my projects [1] [2] especially because a compiler is really better than me to catch many kind of errors. And it's vital to do so.
I've seen too many people that only compile with gcc -g -O2 and optionnally with -Wall when they don't forget it. But from a guy in the compiler business, well, that's just yet-another-illusion that collapses.
Notes
[1] -g -pipe -O2 -funsigned-char -fstrict-aliasing -Wall -Wextra -Wchar-subscripts -Wundef -Wshadow -Wcast-align -Wwrite-strings -Wsign-compare -Wunused -Wno-unused-value -Wuninitialized -Wpointer-arith -Wredundant-decls -Wmissing-prototypes
[2] I usually also add some format string checks, to forbid to pass a non immediate format string, and also -Werror because a warning is in 90% of the cases an error, in 9% of the cases tasteless programming style, and in 0.9% trivial to workaround.
