Is there a way to detect when file dependencies are "accidentally" satisfied?
Let's say there are three headers AAA.h
, BBB.h
and MyLib.h
. MyLib.h
needs to include both AAA.h
and BBB.开发者_如何转开发h
to work properly.
Now, it just happens that BBB.h
also includes AAA.h
in it, but this is strictly due to the implementation, a detail that MyLib.h
should not need to care about.
However, by mistake, the writer of MyLib.h
neglects to include AAA.h
and never notices. This normally doesn't result in an error or warning, for as far as I know. Later on, someone changes the implementation details of BBB.h
so that AAA.h
is no longer needed and thus removed. Now MyLib doesn't compile because internals of library BBB have changed.
Is there a way to error or warn in cases like these? I suspect (if this is even possible) that it would take some kind of annotation in the header being included.
I think it is best to avoid depending on other headers in public interface headers, so that this problem does not come up.
Public interface headers should not contain unnecessary definitions.
There are various tricks to do things without include files. For example, you can declare struct tags manually if you just need a pointer (libraries that only define a typedef frustrate this) and you can use _Bool
instead of bool
to avoid <stdbool.h>
. Unfortunately, many important types such as size_t
and uint32_t
are only defined in headers.
Some packages go so far as to define their own foo_uint32_t
using configure so they need not include <stdint.h>
in their public interface headers. This is quite tricky since the types must be exactly the same to avoid confusion: even if sizeof(unsigned int) == sizeof(unsigned long) == 4
they are different types. Therefore, it may not be worth it.
You are illustrating why including headers sucks as a method to import namespaces.
The only solution I see is discipline. Standard library functions require that you include the appropriate header, your projects should adopt the same standard. Headers such as MyLib.h
should contain only the types it defines and its function prototypes. If it needs to use a certain type to do it's job, the header should be included explicitly, so if it needs a definition from AAA
it should include AAA.h
and if it needs some definition from BBB
it should include BBB.h
, likewise any implementation files (let's say MyLib.c
) should explicitly include all the headers for any definitions it uses, regardless of being sure that MyLib.h
is including them as well. Never assume that a header defines anything implicitly by including other headers.
This is easily checkable using an IDE, which will usually tell you where a name is defined and thus you can easily figure out which include file to use. There may be tools available that do this kind of checking.
精彩评论