Reputation: 179
I'm including netinet/in.h and netinet6/in6.h in that order. This worked for a couple of month. Now I get a compiler error, that the types in in6.h are redefined, because in.h also includes in6.h. I checked in6.h, it starts with:
#ifndef _NETINET_IN_H_INCLUDED
#error "do not include netinet6/in6.h directly, include netinet/in.h. see RFC2553"
#endif
#ifndef _NETINET6_IN6_H_INCLUDED
#define _NETINET6_IN6_H_INCLUDED
...
I must not include it directly, I removed it and the problem is solved. But why did it occur? There is a guard, but it seems not to work. I searched for it, it is never undefined. So why does this problem occur? It may depend on the include order, because in other use cases with different includes this problem doesn't occur. But again: there is a guard, it should never occur, shouldn't it?
The header files are provided by QNX.
Upvotes: 1
Views: 557
Reputation: 215259
The warning is telling you exactly what you need to know. Rather than reading the documentation for the interfaces, which is clear that netinet/in.h
is the header to include to get IP, including IPv6, type and macro definitions, you included some nonstandard, likely implementation-internal, header found via ls
or by reading examples from someone else's wrong code. The interfaces between these headers were not setup to guarantee that this can work (and even if they were, it's not portable), so rather than just leaving it alone and waiting for things to break and users to complain, someone fixed it to give you an error so you know that what you're doing is wrong.
Presumably the mechanism here is that netinet/in.h
is expected to define the macro _NETINET_IN_H_INCLUDED
somewhere early, before it includes the internal header netinet6/in6.h
. Thus, if netinet6/in6.h
gets included before netinet/in.h
, an error is produced, but if it's included from netinet/in.h
or after netinet/in.h
, the #error
directive is skipped.
Since this still allows the wrong usage depending on order, a better approach would be, from netinet/in.h
:
#define _INCLUDING_NETINET_IN_H
#include <netinet6/in6.h>
#undef _INCLUDING_NETINET_IN_H
and having netinet6/in6.h
check for the presence of _INCLUDING_NETINET_IN_H
and error out if it's not defined.
Upvotes: 2