On Tue, 14 Apr 2015, Eitan Adler wrote:

Log:
 ipcs: fix builds that use gcc
        gcc gets annoyed by duplicate declarations

You mean "Fix builds that use a working compiler.  Working compilers
report redundant declarations when requested to do so by the
-Wredundant-decls flag which I recently enabled by raising WARNS to
6."

clang apparently silently ignores the request.

gcc48 still has the following bugs in -Wredundant-decls:
- it redundantly says that redundant declarations are redeclarations.

  Only a very magic type or variable could redundant if it is only
  declared once by the program (including in headers included by
  the program).  Perhaps some predefined type or variable is magic
  enough.  But then the warning should be different.  E.g., main()
  and exit() are known to the compiler except in freestanding
  environments.

  gcc already has special handling for main(), to allow it to be
  declared as either "int main(void);" or "int main(int argc, char
  **argv);", as required to allow the program to use either of
  these.  Declaring one of these in either <stdlib.h> or a compiler
  predeclaration would break use of the other one unless the first
  declaration is magic.  I think gcc skips the warning for its
  builtin predeclaration but wouldn't skip if for a declaration in
  a header.  I think standards don't allow main() to be declared in
  any standard header since they don't require compilers to have
  magic to support this.

  exit() is simpler since it has only 1 correct declaration in
  hosted environments.  It should have a predeclaration in the
  compiler and another one in <stdlib.h>.  The one in <stdlib.h>
  is redundant, but the compiler must not warn about it.  The
  compiler should warn about it for any declaration of it outside
  of standard headers.  The correct practice is to include
  <stdlib.h> to get the declaration.  That gives at least a
  doubly-redundant declaration if the application declares it
  again, and no magic is needed to get the warning.  If the
  application doesn't include <stdlib.h>, then the warning
  should change to one about improper practice when certain
  warnings are enabled.  I think gcc only warns about inconsistent
  uses and the C standard only requires this.  So you should
  be able to non-redundantly declare exit() iff you are careful
  to not include <stdlib.h> and use the same declaration as
  <stdlib.h>.

- it incorrectly says that non-redundant non-redeclarations are
  redundant redeclarations.  C allows building up types by
  supplying additional information in each step.  E.g.:

    void myfunc();
    void myfunc(int);

  gcc48 still warns that the second declaration is a redundant
  redeclaration when it is actually a non-redundant non-redeclaration.
  The first declaration is redundant in some cases (especially
  when there is nothing between the declarations.  Nested incomplete
  function declarations allow arbitrarily long chains of
  non-redundant non-redeclarations to build up a single top-level
  declaration:

    typedef void ifv();         /* incomplete type for func returning void */
    typedef void cfv(int);      /* complete type for func returning void */
    void myfunc();
    void myfunc(ifv *, ifv *);  /* parameters incomplete */
    void myfunc(cfv *, ifv *);  /* complete only first parameter */
    void myfunc(ifv *, cfv *);  /* complete only first parameter */
    /*
     * All non-redundant so far.   The type of myfunc is now complete in
     * Standard C although not in GNC C, so any further declarations of
     * all or parts of it are redundant.
     */

  C also allows building up declarations by adding linkage info.  This
  is even more confusing.

  GNUC also allows building up declarations by adding attribute info
  one or several but not all attributes at a time.  This is less confusing,
  at least for the 1-at-a-time case.  E.g.:

    void panic(const char *, ...);
#ifdef __MUMBLE >= 99
    void panic(const char * restrict, ...);     /* add C99 feature */
#endif
    void panic(const char *, ...) __dead2;      /* add old GNU feature */
    void panic(const char *, ...) __printflike(1, 2); /* newer GNU feature */
    void panic(const char *, ...) __nonnull(1); /* even newer GNU feature */

  Building up types is very confusing so you should rarely do it, but the
  above is almost reasonable.  Adding the restrict qualifier only for C99
  and later is obfuscated in a different way using ifdefs for __restrict.
  The bugs in "gcc -Wredundant-decls" accidentally detect the style bug
  of using the building-up-types feature.  This should be detected
  under a different warning.

  panic(9) is still missing both 'restrict' and __nonnull(1), though it
  needs __nonull() even more than printf([39]) because a null panicstr
  is magic (used for recursion detection).

Bruce
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to