Douglas Gregor wrote:
On Monday 03 March 2003 05:57 am, Russell Hind wrote:
Do (or should) all the bost headers force alignment before all structures/classes and then restore the alignment afterwards?
I don't see any reason that the Boost headers should do this unless they require a certain alignment to operate (and this should never be the case).
The problem goes deeper than the answer addresses. Certain compilers allow one to set the alignment ( and enumeration size, among other command-line changeable qualities which could affect the layout of data ) using #pragmas in the header files themselves. When this is done the compiler uses these settings consistently for the data in that header file no matter what other settings are used in a command-line or IDE build. Setting these very compiler-specific #pragmas protects the header file, and appropriate data it encompasses, from being passed incorrectly between the end-user and the implementation. This ability is a great boon to 3rd party developers of object-oriented software since it protects their users from data layout surprises. Both the Microsoft and Borland compilers support such #pragmas and use the conscientiously for all their RTL and other internal library header files. To say that Boost does not want to use the same technique for particular compilers, when it is available, appears very retrograde to me. Yes, it is possible that Boost may want to say that it doesn't know what the best alignment should be and wants to leave it to developers who build the libraries, but that will not protect the end user unless Boost makes it clear that developers may alter the distribution for themselves in order ot provide the correct alignments through these #pragmas. However, as a practical matter I see little benefit in this approach. The reasons for this is that alignment, enumeration size, and other possible issues relating to data layout are not issues which really need much serious decision. The various compilers do suggest the best default conditions in order to provide the maximum possible speed on various CPUs but in these days of faster CPUs, I personally wouldn't spend too much time worrying about setting other possible values. But whether one chooses to set the default values or other possible values in the appropriate header files through #pragmas, as long as one sets some reasonable value, the compiler will use it and avoid data mismatch. It is not good enough to just say, build your implementation from the command line using some value. This is because if it is not seen in the header file via the appropriate #pragma, when the end-user uses your OOP construct as defined in the header file, the end-user's command-line or IDE value at the time he compiles will be used, and this may not be the same as the value the implementor used to build. Nor is it good enough to use some command-line or IDE value when building your implementation and then telling the end-user that they have to use the exact same value when using your implementation. I hope I don't have to explain why this is so. I will anticipate two final objections to using particular compiler #pragmas in Boost implementation code: 1) It's not mandated in the C++ standard. Yes, #pragmas are implementation defined, but so what. Lots of other Boost code deals with implementation shortcomings in a compiler's adherence to the C++ standard and, while I hope for Boost someday to be able to chuck all those #ifdef and workarounds regarding many compiler's support for the C++ standard in the garbage, as soon as all C++ compilers are 100% conformant as they should theoretically be, surely a relatively benign use of #pragmas to eliminate data layout errors for end-users is worthwhile. 2) Boost developers have to know these #pragma tricks to use them. John Maddock already uses these #pragmas for VC++ and C++ Builder in his Boost.Regex++ library. Others will know them for these compilers, as well as other compilers if they exist, and will be glad to inform Boost developers about them for the compilers which they know about. Adding them to header files is a no-brainer experience for both VC++ and C++ Builder and may be for other compilers which have them. Finally, I admit as a 3rd party developer on Windows who has supplied implementation code for end-users of VC++ and C++ Builder, that I consider it almost "criminal" in a computer programming sense when an end-user is not protected by these #pragmas from possible changes he may make at the command-line or from within an IDE. Surely if Microsoft and Borland have gone out of the way top provide this fail-safe method of eliminating data layout errors, an intelligent implementor can use these methods.