Re: [boost] [asio] header order dependence with <windows.h>

Sebastian Redl wrote:
Олег Абросимов wrote:
1) This issue will continuously frustrate new users, like it was with Serialization lib.
So it will and already does. Personally, I blame Microsoft.
Sorry, what is your point here? Do you claim that boost should follow MS in this question?
2) boost goal is to provide libraries that can be candidates to inclusion into the standard. I can not imagine that order of standard headers inclusion would affect my program well-formedness. It doesn't. <windows.h> is not a standard header, and currently the main issue is including <windows.h> before ASIO headers.
Actually, my code was: #include <boost/process.hpp> #include <boost/asio/deadline_timer.hpp> process - is a boost candidate library by Julio M. Merino Vidal it includes <windows.h> if this lib becomes boost lib then this header order issue will arise again and arise frequently ;-) of course it can be solved by modifying the process lib, but believe it or not - now it is header only too, like asio. and there will be other libs that deal with low-level system APIs that would suffer from the same problem again. It seams for me, that there is a need for common guideline for such a libraries in boost. The filesystem lib can be given as a starting point. It is not header only, it hides it's implementation in .cpp sources. I believe, that any lib that deals with system APIs can not be header only, it must hide it's implementation details to eliminate a chance of headers collisions and as such - should have cpp sources.
It means that while the issue under discussion is not resolved - asio can not be targeted as a proposal for inclusion into the std. and it leads to the conclusion that it doesn't conform to boost goals. sad...
I disagree. The header order dependency is not something inherent to the ASIO library. If ASIO were to become a standard, then this platform-specific issue would be for the compiler vendor to resolve. For example, MS might have to break back compatibility by not getting the <winsock.h> stuff by default in <windows.h> unless a compiler switch is enabled.
Are you joking? In reality the C++ committee can be blocked by any single vendor for any reason. And there the reason is clear - backward compatibility with a huge codebase. Such a library doomed to be rejected.
3) I can not see why you need to include all these platform dependent definitions in each header file. I believe that applying some kind of Bridge pattern would help to localize these platform dependent definitions/declarations in .cpp files only.
ASIO is a header-only library. There are no .cpp files to hide implementation in. It's one of the downsides of header-only libraries.
ok, just introduce .cpp files ;-) Best, Oleg Abrosimov

Олег Абросимов wrote:
Sebastian Redl wrote:
So it will and already does. Personally, I blame Microsoft.
Sorry, what is your point here? Do you claim that boost should follow MS in this question?
I'm saying that any library that must include Windows headers in its own headers for any reason is doomed to this header order dependency because Microsoft's headers have it.
It doesn't. <windows.h> is not a standard header, and currently the main issue is including <windows.h> before ASIO headers.
Actually, my code was: #include <boost/process.hpp> #include <boost/asio/deadline_timer.hpp>
of course it can be solved by modifying the process lib, but believe it or not - now it is header only too, like asio.
It could still be solved on the side of the process library by defining WIN32_LEAN_AND_MEAN before including windows.h. It's sort of a "only include what you need" issue. But I agree that the problem will occur again and again. The problem, as I said, is that the underlying headers are, IMO, broken, and it's very hard to work around the problem, source separation and bridge pattern aside.
I believe, that any lib that deals with system APIs can not be header only, it must hide it's implementation details to eliminate a chance of headers collisions and as such - should have cpp sources.
I'm not disagreeing. However, header-only libraries have their own advantages, such as the ability for core classes to be templates. In a separated model, given the support for external templates (effectively none), all code must be fixed and flexibility provided by runtime polymorphism. That has disadvantages.
Are you joking? In reality the C++ committee can be blocked by any single vendor for any reason. And there the reason is clear - backward compatibility with a huge codebase. Such a library doomed to be rejected.
But it is not "such a library". It's just code that wants to use the networking features of Windows. Every source file dealing in networking stuff, since the creation of winsock2, has had to deal with the same problem: define WIN32_LEAN_AND_MEAN or grab winsock2 before windows. It has always been the rule on Windows that you have to get the networking stuff before the other stuff. I don't see that as a valid blocking reason. (All right, so my view may be idealistic. Still, didn't we, as the programmers, have to deal with this long enough? Isn't it about time MS looked forward for their headers? How much code that actually requires Winsock1 will be compiled on VS.Net 2007 or 08 or whatever the next version will be?) Sebastian Redl

Sebastian Redl wrote:
Oleg Abrosimov wrote:
Actually, my code was: #include <boost/process.hpp> #include <boost/asio/deadline_timer.hpp>
of course it can be solved by modifying the process lib, but believe it or not - now it is header only too, like asio.
Oleg, if the process lib is including windows.h then you can equally argue that boost/process.hpp is sensitive to header ordering because this would work: #include <winsock2.h> #include <boost/process.hpp> and this wouldn't: #include <winsock2.h> #include <boost/process.hpp> It should probably be modified to define WIN32_LEAN_AND_MEAN before including before including windows.h. E.g. using the mechanism that was described here: http://article.gmane.org/gmane.comp.lib.boost.devel/148309 Yes, it is already on my todo list to do something about this for asio (probably adopting the approach used by the interprocess library rather than the bridge pattern). However there are plenty of other things that have a higher priority, so it won't happen for quite a while. In the meantime, it is my opinion that it is sufficient to provide the following guarantee: if a program uses boost and std headers only, then the headers need not be in any particular order. If a program explicitly includes windows.h, winsock2.h or a similar header then the program has to care about header order, because that is the nature of the Windows SDK.
I'm not disagreeing. However, header-only libraries have their own advantages, such as the ability for core classes to be templates. In a separated model, given the support for external templates (effectively none), all code must be fixed and flexibility provided by runtime polymorphism. That has disadvantages.
Yep. Another potential disadvantage of a separated model is gratuitous copying or memory allocations resulting from mapping external to implementation types. For example, scatter-gather operations use WSABUF on windows -- if that type is to be completely hidden, then I need to copy the buffer pointers to a separate array first. While I'm hopeful these problems can be solved, they are why I'm leaning towards the approach used by interprocess as a simpler solution. That is, to declare/define the required types and functions myself instead of including windows header files.
Are you joking? In reality the C++ committee can be blocked by any single vendor for any reason. And there the reason is clear - backward compatibility with a huge codebase. Such a library doomed to be rejected.
The networking proposal doesn't say that implementations must be header-only. An implementor can completely hide the implementation details.
But it is not "such a library". It's just code that wants to use the networking features of Windows. Every source file dealing in networking stuff, since the creation of winsock2, has had to deal with the same problem: define WIN32_LEAN_AND_MEAN or grab winsock2 before windows. It has always been the rule on Windows that you have to get the networking stuff before the other stuff. I don't see that as a valid blocking reason. (All right, so my view may be idealistic. Still, didn't we, as the programmers, have to deal with this long enough? Isn't it about time MS looked forward for their headers? How much code that actually requires Winsock1 will be compiled on VS.Net 2007 or 08 or whatever the next version will be?)
I'm not holding my breath ;) Cheers, Chris

Christopher Kohlhoff wrote:
Sebastian Redl wrote:
But it is not "such a library". It's just code that wants to use the networking features of Windows. Every source file dealing in networking stuff, since the creation of winsock2, has had to deal with the same problem: define WIN32_LEAN_AND_MEAN or grab winsock2 before windows. It has always been the rule on Windows that you have to get the networking stuff before the other stuff. I don't see that as a valid blocking reason. (All right, so my view may be idealistic. Still, didn't we, as the programmers, have to deal with this long enough? Isn't it about time MS looked forward for their headers? How much code that actually requires Winsock1 will be compiled on VS.Net 2007 or 08 or whatever the next version will be?)
I'm not holding my breath ;)
Neither am I. It is not like MS is an entity that provides a global consistent view of all its products. The windows.h header (and subcomponents) is the definition of the Win32 API in glorious C-style provided by the OS implementers. Their view is: "If any C++ compiler cannot handle that - tough!". Talk about an immovable object! Bo Persson

On 12/20/06, Christopher Kohlhoff <chris@kohlhoff.com> wrote:
I'm not disagreeing. However, header-only libraries have their own advantages, such as the ability for core classes to be templates. In a separated model, given the support for external templates (effectively none), all code must be fixed and flexibility provided by runtime polymorphism. That has disadvantages.
If the raw networking code was wrapped in a very thin wrapper (that really just isolated you from the <windows.h> stuff, perhaps using untypedef'ed, but compatible types (e.g. unsigned long in place of DWORD etc) to avoid mappings, then I don't see that the wrappers need add much, if any, overhead. The real ASIO code could still be rife with templates and compile-type polymorphism. I don't see that you'd need that for the internal thin wrapper. You could even go as far as to put the wrapper implementation in a header file and have the option of using a lib that has already included it in a translation unit, or include it yourself if you don't want the lib dependancy (something I'd like to see in other boost libs, for that matter). Personally I would really like to see libraries like ASIO and Process be free of windows.h dependancies in the user headers.
Yep. Another potential disadvantage of a separated model is gratuitous copying or memory allocations resulting from mapping external to implementation types. For example, scatter-gather operations use WSABUF on windows -- if that type is to be completely hidden, then I need to copy the buffer pointers to a separate array first.
As I said above, the types need not be "completely hidden". Another possibility (not sure how viable this is here, but I have done this in other, simpler, cases) is to make the declarations you need from windows.h/ winsock2.h yourself, so you don't even need to write the #includes anywhere! Not sure if you can get around the problem of the redefinitions if winsock.h is included first that way - but just a thought. Regards, [)o IhIL..
participants (5)
-
Bo Persson
-
Christopher Kohlhoff
-
Phil Nash
-
Sebastian Redl
-
Олег Абросимов