Tim Ruehsen tim.ruehsen@gmx.de writes:
#define NONNULL(args) __attribute__ ((nonnull args))
Yes, functions with several non-null args than need several NONNULL(x) occurrences.
I don't think so. NONNULL((1,3,5)) should work, with "(1,3,5)" treated as a single argument by the preprocessor. I would actually prefer to have NONNULL declaration on each argument in question, just like UNUSED, but if I understand it correctly, that won't work.
The idea of nonnull is to enable the compiler detecting possible NULL arguments where they must not be. E.g. char *s=NULL; strlen(s); would let the compiler print a warning.
I'm not entirely convinced about the usefulness of that.
At the same time, when optimizing a function with a nonnull argument, gcc optimizes away checks against NULL for the appropriate variables.
I'm not entirely convinced that makes for any real improvements of performance on real code. And I think I'd rather get a warning from the compiler about a useless comparison (like, like gcc warns for for unsigned x = ...; if (x >= 0)...) than having the optimizer silently remove the code.
In particular, if I have a funtion where a pointer must not be NULL, and I have an assert (p != NULL); to that effect, then I will *not* consider it an improvement if the compiler decides to remove that assert.
Is there anything more useful and interesting that the compiler can do, knowing that a pointer can't be NULL?
Sorry if I sound extremely negative. I think nonnull declarations in header files could serve some purpose for documentation, but I doubt it will improve performance or make it easier to find real bugs.
Since gcc can't detect indirect NULL values, the function may crash the process.
I'm not sure what you mean here, but I guess it won't work well to have the nonnull attribute propagate (say, in the same way as const). With the following code,
int foo (const char *a, const char *b) __attribute__ ((nonnull) { return strcmp (a, b); }
int bar (const char *a) { return foo (a, "foo"); }
should gcc issue a warning (since as far as we have told the compiler, bar (NULL) is allowed, but that is not allowed for it's call to foo)? Does it, or clang, issue warnings for such code?
- Since when (release and year) is it supported by gcc?
I found it to be for gcc >= 3.3, see http://ohse.de/uwe/articles/gcc-attributes.html#func-nonnull
Released back in 2004 (http://gcc.gnu.org/releases.html). Then I guess it shouldn't be too bad to use it unconditionally when compiling with gcc. Or check the gcc version predefines, that's not a very big hassle.
The reason I used nonnull were several compiler warnings. The current libc6 header files seem to use nonnull by default (gcc 4.7.1, libc6 2.13).
Can you quote the warnings in question? I'd like to understand why it complains.
Maybe there should be -std=c89 in den CFLAGS to prevent that ?
That would make sense. Or at least *some* flag to issue warnings for c99 additions like C++-style comments and declarations not at the start of a block.
Regards, /Niels