svn commit: r231939 - head/sys/net80211
Aleksandr Rybalko
ray at freebsd.org
Tue Feb 21 00:10:33 UTC 2012
On Tue, 21 Feb 2012 04:57:13 +1100 (EST)
Bruce Evans <brde at optusnet.com.au> wrote:
> On Mon, 20 Feb 2012, Aleksandr Rybalko wrote:
>
> > Log:
> > Remove redundant forward declaration of struct ieee80211com.
>
> Thanks, but it now has 1 redundant forward declarations of this
> instead of 2. There is another section with 3 forward declarations
> which are all redundant and bogus.
>
> Since programmers apparently don't understand C's scope rules for
> declarations of incomplete structs (these declarations declare just
> the struct tag), it would be useful for the compiler to warn about
> bogus ones.
Seems me too :)
>
> The remaining 3 bogus ones are before a struct that uses pointers to
> the incomplete structs for its struct members. C's scope rules work
> right in this case, and so any pointer declaration self-declares the
> same incomplete struct that a previous forward declaration would (thus
> any previous purely-forward declaration is bogus, and `any' applies to
> all 3 here), and also forward-declares the incomplete struct for the
> rest of the file (so any later forward declaration is bogus).
So I will try to remove another when complete with understanding of
that paragraph of ‘K&R C’ :)
>
> > Modified: head/sys/net80211/ieee80211_node.h
> > ==============================================================================
> > --- head/sys/net80211/ieee80211_node.h Mon Feb 20 13:59:24
> > 2012 (r231938) +++ head/sys/net80211/ieee80211_node.h
> > Mon Feb 20 15:05:21 2012 (r231939) @@ -299,8 +299,6 @@
> > ieee80211_unref_node(struct ieee80211_no *ni =
> > NULL; /* guard against use */ }
> >
> > -struct ieee80211com;
> > -
> > void ieee80211_node_attach(struct ieee80211com *);
> > void ieee80211_node_lateattach(struct ieee80211com *);
> > void ieee80211_node_detach(struct ieee80211com *);
>
> OTOH, the scope rules for prototypes (and function definitions) don't
> work right. Any declaration of an incomplete struct in the function's
> parameters is purely local to the extent that it doesn't affect the
> rest of the file, and to go with this the declaration must be of a
> struct that is incapable being passed, unless the struct has already
> been declared, perhaps incompletely. So some prototypes need an
> explicit forward declaration of the struct which is sometimes placed
> just before the prototype or at the beginning of a block of
> prototypes. But in many cases, such a declaration is bogus because
> the struct has already been declared (incompletely and
> self-referentially) as part of the declaration of a pointer struct
> member. Normal order puts (complete) struct declarations before
> prototypes and thus gives the declaration more often than other
> orders would, and it is good to depend on it since the need for
> forward declarations before prototypes is just a bug in the scope
> rules for prototypes so we shouldn't have to write extra code to work
> around it.
>
> Compilers can be relied to warn about cases where the explicit forward
> declarations are necessary, except in cases of header pollution where
> most but not all of the necessary forward declarations are provided
> accidentally by pollution in other headers (you start getting errors
> if the pollution is fixed or moved, or if the application doesn't
> happen to include enough headers to supply as much pollution as it
> used to). I usually find minimal sets of forard declarations by first
> fixing all pollution and then compiling the header without any other
> includes before it; then remove all forward declarations and add back
> the ones that cause compilation failures. Without fixing the
> pollution, you can't rely on compilation failures to find all the
> necessary ones.
>
> Pollution and non-pollution in other headers make it difficult for
> a -Wbogus-declarations option to be made usable. The
> -Wredundant-decls options option is only for variables and
> prototypes, and is buggy for non-redundant declarations where the
> declaration is built up, with types and other qualities being
> completed at each step. Considerable ifdefing was needed to make this
> usable in the FreeBSD kernel, and it is only enabled by WARNS >= 6 in
> userland. Similar ifdefing for struct tags might be even more
> painful. Now it is clearer that some declarations are built up -- a
> full struct definition is not redundant when it completes an
> incomplete struct declaration. The self-forward declaration of
> "struct foo" in "struct foo *bar" is never redundant, and it makes
> any previous forward declaration of "struct foo" redundant, but the
> compiler can only usefully warn about this if the previous one is
> guaranteed to be in scope (thus if it is in another header, it may or
> not be bogus, depending on whether that header always does it and is
> always included, and this is so in all other headers).
>
> Bruce
Thanks for good comments Bruce!
WBW
--
Aleksandr Rybalko <ray at freebsd.org>
More information about the svn-src-head
mailing list