[Development] Header file cleanups
BRM
bm_witness at yahoo.com
Thu Mar 1 16:43:19 CET 2012
> From: Thiago Macieira <thiago.macieira at intel.com>
>On quinta-feira, 1 de março de 2012 12.44.47, Mathias Hasselmann wrote:
>> > According to the book it is. But in practice it happens all the time, and
>> > we know it.
>>
>> To which book? C++ compilers and IDEs give zero support in enforcing
>> direct includes. Considering the mess GNU libc headers are, I even
>> wonder how to formulate automatic checks for direct includes.
>
>Adding includes is also a source-incompatible change in some situations and we
>can't avoid it. Adding a new include means new symbols become defined, new
>overloads are produced.
>
>For example, the following code, found in WebKit, compiles under C++98 + POSIX
>or C++98 + C99:
>
> #include <cmath>
> using namespace std;
> int foo() { return isnan(0.); }
>
>But it does not compile under C++11 because there's now a std::isnan. It
>happens because cmath indirectly includes math.h, which strictly speaking it
>shouldn't.
>
>Another example of things breaking are Q_DECLARE_METATYPE. If you #include a
>header that declares a certain type a metatype, you'll break everyone's code
>that also had that macro.
Agreed. And compilers are changing in that respect. As some of my code has moved from GCC 4.2 to newer (GCC 4.5/4.6) compilers,
I've had to go and figure out includes because of things ending up under indirect includes for one reason or another.
So I agree with Thiago in that this would be a bug.
>> Considering this weakness of C and C++ some have come to the conclusion
>> that indirect includes are part of the API. Removing redundant include
>> directives from released headers actually is an API break in C/C++.
>
>Which is why I am saying that, in my book, those changes are acceptable and
>user code will need to adapt. Therefore, they don't count as an API break. If
>you need to use feature X, you need to #include the header that provides it
>and you need to link to the library that contains it. Depending on indirect
>inclusion and on indirect linking is a bug.
It also leads to a chaos. (More below)
>> The GNOME guys went the pragmatic approach and now forbid direct
>> includes. You always must include the module headers for GTK+ and
>> friends now (unless explicitly asking for trouble):
>>
>> #if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
>> #error "Only <gtk/gtk.h> can be included directly."
>> #endif
>>
>> Sadly, considering the slowness of g++ and the complexity of Qt, I doubt
>> this is a reasonable approach for Qt.
>
>Yup.
Interesting.
What is most interesting though in this discussion is that there is a major use-case on how indirect includes cause major problems - e.g. Microsoft.
For years, Microsoft advocated the use of simply including the "windows.h" header file. However, this ultimately led to a very very big problem - one that ended up with circular dependencies between user space and kernel space. It also cost them a lot of money to correct in their own code - having first developed a version of Windows that while it works was so poorly performing they couldn't deliver it at a cost of 3 years of development, only to throw it out and start over with major efforts towards reducing the dependency levels and another 3 years of development to produce what because Windows Vista, and follow on to Windows 7 at substantially less work. As a result, they also no longer advocate the use of 'windows.h' (they seem to have removed it from the newer SDKs), and the header levels have broken down. The new structure they have is far more resilient, leaner, and easier to work with. (Note, this was just one of the many issues they had during
the development of what became Vista. But it was a big issue.)
I won't advocate how Gtk is doing it - it's just as bad as the old Windows.h for Microsoft - but that's there issue, not ours.
All-in-all, why would we want to continue supporting something that could cause the same problems for our users? Sure, there will be a small source-compile breakage as the changes are made (and I agree 5.0 is not the right timing for it at the moment), but ultimately it will lead to a better Qt Platform for developers to build on. If Qt users continue those practices in their own projects, then that's there issue - but let's not encourage it ourselves.
$0.02
Ben
P.S. Personally, even in my Windows development I always tried to move away from using Windows.h; it was a pain to figure out all the headers (since MS never told you until they released Vista) but it was doable.
More information about the Development
mailing list