Loading ...
Sorry, an error occurred while loading the content.
 

[boost] Re: Boost header guidelines

Expand Messages
  • John Maddock
    Paul - ... non-boost version... is irrelevant to me - I don t need to worry about i18n issues. What are the issues with
    Message 1 of 26 , Oct 2, 1999
      Paul -
      >That's a real disappointment. If so, I'd prefer to have the current
      non-boost version...<

      as you can continue to do....

      <locale> is irrelevant to me - I don't need to worry about i18n issues.
      What
      are the issues with <iterator> and <memory>?<

      Ok here are the problems that come to mind:

      <memory>

      std::allocator is non standard - there is no Rebind<U> nested template
      class - either we have to allocate "chunks" of sizeof(T), and live with
      inefficiency where sizeof(T) is large, or use a byte based allocator as the
      default (cf SGI's allocators). Fix requires alternate typedefs in
      container class - so the minimum requirement is a BOOST_NO_STD_ALLOCATOR
      macro (although possibly BOOST_NO_MEMBER_TEMPLATES could double up here).

      <iterator>

      There are no partial template specialisations allowed in VC6, so
      iterator_traits<> fails for built in types (pointers), this makes some code
      impossible, other code is possible but requires workarounds - for example
      using a function return type to determine the iterator type (again cf SGI
      STL). Minimum workaround requirement is a macro BOOST_NO_PARTIAL_SPEC.

      <locale>

      Calling functions with explicit template args is not supported, so
      use_facet and has_facet are non-standard. Another maco anyone?

      Others:

      MSVC can't deal with template function partial ordering - making some
      useful algorithm overloads impossible - requires another macro
      BOOST_NO_PARTIAL_ORDERING.


      **this is not a diffinitive list** it includes only unsupported
      compiler/standard library features, not compiler bugs (like occationally
      flakey qualified name lookup).

      My reasoning is that if I'm going to do a rewrite as part of a wider
      pattern-matching stategy (as I'm planning), I may as well see how few
      macros I can get away with in the short term, in the knowledge that by the
      time the project is complete, VC7 will probably be out and about, and gcc
      will have acquired <locale> support.

      - John
    • Moore, Paul
      From: John Maddock [mailto:John_Maddock@compuserve.com] ... Yuk. I hadn t realised that. ... Again yuk. ... ??!?!?!?!?! I was *sure* I d used this in MSVC 6,
      Message 2 of 26 , Oct 4, 1999
        From: John Maddock [mailto:John_Maddock@...]
        > Ok here are the problems that come to mind:
        >
        > <memory>
        >
        > std::allocator is non standard - there is no Rebind<U> nested template
        > class - either we have to allocate "chunks" of sizeof(T), and

        Yuk. I hadn't realised that.

        >
        > <iterator>
        >
        > There are no partial template specialisations allowed in VC6, so
        > iterator_traits<> fails for built in types (pointers), this
        > makes some code

        Again yuk.

        >
        > <locale>
        >
        > Calling functions with explicit template args is not supported, so
        > use_facet and has_facet are non-standard. Another maco anyone?

        ??!?!?!?!?! I was *sure* I'd used this in MSVC 6, and found it to work. But
        you're right, it doesn't. OK, I give up. MSVC is utterly broken, even in
        version 6.

        > MSVC can't deal with template function partial ordering - making some
        > useful algorithm overloads impossible - requires another macro
        > BOOST_NO_PARTIAL_ORDERING.

        [Too late, I'd already given up :-)]

        > My reasoning is that if I'm going to do a rewrite as part of a wider
        > pattern-matching stategy (as I'm planning), I may as well see how few
        > macros I can get away with in the short term, in the knowledge that
        > by the time the project is complete, VC7 will probably be out and about,
        > and gcc will have acquired <locale> support.

        Sadly, MSVC is and will remain a very widely used platform. Pressure to
        conform to the standard needs to remain high. Raising awareness of these
        issues is also important (I didn't know about them...) Does/can anybody do a
        regular posting, say to comp.lang.c++, and microsoft.public.whatever.vc++
        listing the currently know set of non-conformances?

        BTW, from rumours I hear, MSVC 7 seems to be targetted at adding
        non-standard "improvements" to the language, rather than working on
        conformance. "Embrace and extend", again?

        Also, even if MSVC 7 is better conforming, the upgrade price will be high,
        so many people will stay on MSVC 6 for some time. Possibly including me :-(

        Now I'm really depressed...

        Paul.
      • James Curran/MVP
        ... use_facet and has_facet are non-standard. Another maco anyone?
        Message 3 of 26 , Oct 4, 1999
          >> >> Calling functions with explicit template args is not supported, so
          use_facet and has_facet are non-standard. Another maco anyone? << <<

          >> ??!?!?!?!?! I was *sure* I'd used this in MSVC 6, and found it to work.
          But you're right, it doesn't. OK, I give up. MSVC is utterly broken, even in
          version 6. <<

          Well, not entirely broken...
          template <typename T>
          T func()
          { return T(); }
          :
          int n = func<int>();

          will fail. However:

          template <typename T>
          T func(T* t = NULL)
          { return T(); }
          :
          int n = func<int>();


          will succeed. It's really cheesy work-around, but it does make life with VC
          a bit more bearable.
        • John Maddock
          Paul - ... non-standard improvements to the language, rather than working on conformance. Embrace and extend , again? Also, even if MSVC 7 is better
          Message 4 of 26 , Oct 5, 1999
            Paul -

            >BTW, from rumours I hear, MSVC 7 seems to be targetted at adding
            non-standard "improvements" to the language, rather than working on
            conformance. "Embrace and extend", again?

            Also, even if MSVC 7 is better conforming, the upgrade price will be high,
            so many people will stay on MSVC 6 for some time. Possibly including me :-(
            <

            I'll see what happens - as I said VC6 support is very much possible - I
            already have the workarounds required from regex++ - the problem is the
            number of macros and workarounds required - and debugging/maintaining what
            is in effect two (or more) separate code bases. Really I wondered what
            other boost members thought - I'm happy to put the workarounds in - it just
            doesn't quite fit with the ethos of boost as far as I can see.

            John.
          • Dave Abrahams
            ... Just a thought: If the problem is more one of non-standard library components than of missing language support, you could considering requiring the STLPort
            Message 5 of 26 , Oct 5, 1999
              > Paul -
              >
              >>BTW, from rumours I hear, MSVC 7 seems to be targetted at adding
              > non-standard "improvements" to the language, rather than working on
              > conformance. "Embrace and extend", again?
              >
              > Also, even if MSVC 7 is better conforming, the upgrade price will be high,
              > so many people will stay on MSVC 6 for some time. Possibly including me :-(
              > <
              >
              > I'll see what happens - as I said VC6 support is very much possible - I
              > already have the workarounds required from regex++ - the problem is the
              > number of macros and workarounds required - and debugging/maintaining what
              > is in effect two (or more) separate code bases. Really I wondered what
              > other boost members thought - I'm happy to put the workarounds in - it just
              > doesn't quite fit with the ethos of boost as far as I can see.
              >
              > John.

              Just a thought:
              If the problem is more one of non-standard library components than of
              missing language support, you could considering requiring the STLPort for
              using regex++ under VC6.

              -Dave
            • John Maddock
              Dave - ... If the problem is more one of non-standard library components than of missing language support, you could considering requiring the STLPort for
              Message 6 of 26 , Oct 6, 1999
                Dave -

                >Just a thought:
                If the problem is more one of non-standard library components than of
                missing language support, you could considering requiring the STLPort for
                using regex++ under VC6.<

                No it doesn't really help, it just changes the way in which fixes have to
                be applied, I get the impression that dinkumware did their best, given the
                compiler limitations, in fact I get the impression that they are deeply
                frustrated with the compilers capabilities given that they usually get the
                blaim for the non-standard library.

                I think perhaps what I will do is create a file something like
                "dirty_ugly_vc6_hacks.hpp" with the fixes and macros required for VC6
                support, in the assumption that the file should either be subsumed into
                config.hpp or depreciated at a later date, once boost users can see what's
                involved they can choose what the ultimate fate of the file is.

                - John.
              • Ed Brey
                ... The dinkumware library that ships with VC6 suffers from two problems: lack of compiler support and age. For the former, as you stated, switching to
                Message 7 of 26 , Oct 6, 1999
                  > From: John Maddock [mailto:John_Maddock@...]
                  >
                  > >Just a thought:
                  > If the problem is more one of non-standard library components than of
                  > missing language support, you could considering requiring the STLPort for
                  > using regex++ under VC6.<
                  >
                  > No it doesn't really help, it just changes the way in which fixes have to
                  > be applied, I get the impression that dinkumware did their best, given the
                  > compiler limitations, in fact I get the impression that they are deeply
                  > frustrated with the compilers capabilities given that they usually get the
                  > blaim for the non-standard library.

                  The dinkumware library that ships with VC6 suffers from two problems: lack of
                  compiler support and age. For the former, as you stated, switching to STLPort
                  won't make much difference. However, STLPort does provide a library that is
                  based on the C++ standard, rather than a draft. This makes a big difference,
                  for instance, if you want to use std::auto_ptr (yes, it is still useful, even
                  in the presence of the boost smart pointers).

                  Also, STLPort makes use of features that have been added to VC6 since the
                  dinkumware version was frozen. This makes a difference when using predicate
                  versions of member functions, since the dinkumware version unnecessarily hard
                  codes the predicates because of its out-of-date assumption that member
                  template functions are unsupported.
                • Steinar Bang
                  ... In addition to being based on the draft standard, the library shipped with VC6 (and VC5 for that matter), has eg.:
                  Message 8 of 26 , Oct 7, 1999
                    >>>>> "Ed Brey" <brey@...>:

                    > The dinkumware library that ships with VC6 suffers from two
                    > problems: lack of compiler support and age. For the former, as you
                    > stated, switching to STLPort won't make much difference. However,
                    > STLPort does provide a library that is based on the C++ standard,
                    > rather than a draft. This makes a big difference, for instance, if
                    > you want to use std::auto_ptr (yes, it is still useful, even in the
                    > presence of the boost smart pointers).

                    In addition to being based on the draft standard, the library shipped
                    with VC6 (and VC5 for that matter), has eg.:
                    http://msdn.microsoft.com/visualc/stl/FAQ.HTM#Q4

                    Fixes to the above bug, and many others can be found at
                    http://www.dinkumware.com/vc_fixes.html

                    But even with these fixes there is a problem in that some templates
                    are instantiated in the buggy version in the runtime DLL, and that
                    even with the patched header the buggy versions will be used (this is
                    the case of eg. string).
                  • Beman Dawes
                    ... has ... getting ... B ... compilers ... compilers, ... seat. Ah! I see now that there are two techniques for using BOOST_NO_STDC_NAMESPACE: 1)
                    Message 9 of 26 , Oct 8, 1999
                      Ed Brey wrote:

                      >> >we could use using declarations to quickly pick up the names:
                      >> >
                      >> >#ifdef BOOST_NO_NAMESPACE_FOR_STDC
                      >> > #include <cstddef>
                      >> > #include <cstdlib>
                      >> > #include <cmath>
                      >> > namespace std {
                      >> > using ::size_t; using ::ptrdiff_t;
                      >> > ...
                      >> >#endif
                      >>
                      >> Ed, I think your solution above is a really good one.
                      >>
                      >> Typo: the #ifdef should be after rather than before the #includes.
                      >
                      >Actually, the #include location is by design, reason being that for
                      >conforming implementations, the "large compiler vendor" workaround
                      has
                      >absolutely zero effect. In particular, libraries should never count
                      >on config.hpp including any headers; they should merrily assume that
                      >the implementation is conforming. So if a library uses std::size_t,
                      >it should include <cstdlib>. If the implementation on which the
                      >library is compiled happens to be buggy, <cstdlib> will end up
                      getting
                      >#included twice, which is fine.
                      >
                      >In general, if a translation unit includes library L that needs
                      >headers A and B, on a conforming compiler we want only headers A and
                      B
                      >to be included, since that is what we'd naturally do if all
                      compilers
                      >were conferment. Only when working with a buggy compiler do we want
                      >to fall back to workarounds, which may involve extra includes. This
                      >is strict adherence to the policy of writing for conferment
                      compilers,
                      >with workarounds for buggy compilers taking a non-intrusive back
                      seat.

                      Ah! I see now that there are two techniques for using
                      BOOST_NO_STDC_NAMESPACE:

                      1) boost/config.hpp #defines (for non-conforming compilers only)
                      BOOST_NO_STDC_NAMESPACE, and also your code above as written. A
                      boost header needing cstdlib then simply contains:

                      #include <boost/config.hpp>
                      #include <cstdlib>

                      2) boost/config.hpp #defines (for non-conforming compilers only)
                      BOOST_NO_STDC_NAMESPACE, period. Then it is up to individual boost
                      headers (if they wish) to supply the workaround:

                      #include <boost/config.hpp>
                      #include <cstdlib>
                      #ifdef BOOST_NO_STDC_NAMESPACE
                      # namespace std { using ::size_t; using ::ptrdiff_t; }
                      #endif

                      These techniques can be combined; (1) could be used for the very
                      commonly used headers such as cstdlib, cstddef, and maybe cstring,
                      while (2) could be used for the other <c...> headers.

                      Comments?

                      --Beman
                    • Dave Abrahams
                      ... I haven t been following this discussion, but importing names into std strikes me as a bit regressive, especially when we have our own namespaces which we
                      Message 10 of 26 , Oct 8, 1999
                        > 2) boost/config.hpp #defines (for non-conforming compilers only)
                        > BOOST_NO_STDC_NAMESPACE, period. Then it is up to individual boost
                        > headers (if they wish) to supply the workaround:
                        >
                        > #include <boost/config.hpp>
                        > #include <cstdlib>
                        > #ifdef BOOST_NO_STDC_NAMESPACE
                        > # namespace std { using ::size_t; using ::ptrdiff_t; }
                        > #endif
                        >
                        > These techniques can be combined; (1) could be used for the very
                        > commonly used headers such as cstdlib, cstddef, and maybe cstring,
                        > while (2) could be used for the other <c...> headers.
                        >
                        > Comments?

                        I haven't been following this discussion, but importing names into std
                        strikes me as a bit regressive, especially when we have our own namespaces
                        which we can use.

                        -Dave
                      • John Maddock
                        Beman, ... commonly used headers such as cstdlib, cstddef, and maybe cstring, while (2) could be used for the other headers. Comments?
                        Message 11 of 26 , Oct 9, 1999
                          Beman,

                          >These techniques can be combined; (1) could be used for the very
                          commonly used headers such as cstdlib, cstddef, and maybe cstring,
                          while (2) could be used for the other <c...> headers.

                          Comments?<

                          That seems to work OK, even in the presense of duplicate using
                          declarations, as you say add maybe cstdlib and cstddef to config.hpp, other
                          boost libraries can deal with other headers on a case by case basis - it
                          may result in some duplication but this seems to be harmless.


                          Dave,

                          >I haven't been following this discussion, but importing names into std
                          strikes me as a bit regressive, especially when we have our own namespaces
                          which we can use.<

                          The point is to make non-conforming C standard libraries behave as if they
                          were conforming - I guess an alternative would be something like:

                          #include <cstdlib>

                          namespace boost{

                          #ifdef BOOST_NO_STDC_NAMESPACE
                          using ::size_t;
                          #else
                          using std::size_t;
                          #endif

                          /* code goes here */

                          } // namespace boost

                          The downside is that if the user then adds:

                          using namespace boost;

                          they get most of namspace std as well as boost.

                          On the other hand we could use:

                          #include <cstdlib>

                          namespace boost{
                          namespace undocumented{

                          #ifdef BOOST_NO_STDC_NAMESPACE
                          using ::size_t;
                          #else
                          using std::size_t;
                          #endif

                          /* code goes here */

                          } // namespace undocumented
                          using boost::undocumented::some_public_symbol;
                          } // namespace boost

                          which allows some degree of implementation hiding even when the code
                          consists of "all headers", the down side is that it requires more work for
                          some of the simpler headers. BTW this approach is not mutually exclusive
                          with Beman's (1) or (2).

                          Just when I though that this message thread had been put to bed :-)

                          - John.
                        • Dave Abrahams
                          ... Precisely what I had in mind. ... most? This only looks like one name. ... Why bother with this using declaration at all? With it you still have the same
                          Message 12 of 26 , Oct 9, 1999
                            > The point is to make non-conforming C standard libraries behave as if they
                            > were conforming - I guess an alternative would be something like:
                            >
                            > #include <cstdlib>
                            >
                            > namespace boost{
                            >
                            > #ifdef BOOST_NO_STDC_NAMESPACE
                            > using ::size_t;
                            > #else
                            > using std::size_t;
                            > #endif
                            >
                            > /* code goes here */
                            >
                            > } // namespace boost

                            Precisely what I had in mind.

                            > The downside is that if the user then adds:
                            >
                            > using namespace boost;
                            >
                            > they get most of namspace std as well as boost.

                            'most?'
                            This only looks like one name.

                            > On the other hand we could use:
                            >
                            > #include <cstdlib>
                            >
                            > namespace boost{
                            > namespace undocumented{
                            >
                            > #ifdef BOOST_NO_STDC_NAMESPACE
                            > using ::size_t;
                            > #else
                            > using std::size_t;
                            > #endif
                            >
                            > /* code goes here */
                            >
                            > } // namespace undocumented
                            > using boost::undocumented::some_public_symbol;

                            Why bother with this using declaration at all?
                            With it you still have the same drawback you described above if the user
                            writes 'using namespace boost' (which, by the way, I don't believe we should
                            go out of our way to make safe -- since that's well nigh impossible).

                            > } // namespace boost

                            > which allows some degree of implementation hiding even when the code
                            > consists of "all headers", the down side is that it requires more work for
                            > some of the simpler headers. BTW this approach is not mutually exclusive
                            > with Beman's (1) or (2).

                            The above paragraph is unintelligible to me. Perhaps I've missed the
                            background material?

                            -Dave
                          • Alan Griffiths
                            In message , Dave Abrahams writes ... An option I ve been toying with is: #include
                            Message 13 of 26 , Oct 10, 1999
                              In message <199910092159.RAA20307@...>, Dave Abrahams
                              <abrahams@...> writes
                              >> The point is to make non-conforming C standard libraries behave as if they
                              >> were conforming - I guess an alternative would be something like:
                              >>
                              >> #include <cstdlib>
                              >>
                              >> namespace boost{
                              >>
                              >> #ifdef BOOST_NO_STDC_NAMESPACE
                              >> using ::size_t;
                              >> #else
                              >> using std::size_t;
                              >> #endif
                              >>
                              >> /* code goes here */
                              >>
                              >> } // namespace boost
                              >

                              An option I've been toying with is:

                              #include <cstdlib>

                              namespace boost {

                              #ifdef BOOST_NO_STDC_NAMESPACE
                              namespace std {
                              using ::size_t;
                              }
                              #endif

                              // Make use of std::size_t
                              }

                              This avoids "polluting" the boost namespace.
                              --
                              Alan Griffiths (alan@...) http://www.octopull.demon.co.uk/
                              ACCU Chairman (chair@...) http://www.accu.org/
                            • John Maddock
                              Dave - ... With it you still have the same drawback you described above if the user writes using namespace boost (which, by the way, I don t believe we
                              Message 14 of 26 , Oct 10, 1999
                                Dave -

                                > On the other hand we could use:
                                >
                                > #include <cstdlib>
                                >
                                > namespace boost{
                                > namespace undocumented{
                                >
                                > #ifdef BOOST_NO_STDC_NAMESPACE
                                > using ::size_t;
                                > #else
                                > using std::size_t;
                                > #endif
                                >
                                > /* code goes here */
                                >
                                > } // namespace undocumented
                                > using boost::undocumented::some_public_symbol;
                                > } // namespace boost

                                >Why bother with this using declaration at all?
                                With it you still have the same drawback you described above if the user
                                writes 'using namespace boost' (which, by the way, I don't believe we
                                should
                                go out of our way to make safe -- since that's well nigh impossible).<

                                The point with this method is that only documented symbols are in visible
                                in namespace boost - everything that's private to the implementation (and
                                undocumented) - whether helper classes, typedefs or using declarations -
                                remains in namespace boost::undocumented and is *not* imported into
                                namespace boost, or into the global namespace if there is a "using
                                namespace boost" declaration. This is what I meant in this case by
                                "implementation hiding" - only documented types should be present in
                                namespace boost - anything else can be hidden away in a private namespace.
                                BTW the standard more or less mandates this for namespace std - including a
                                particular header should declare only types documented for that header in
                                namespace std - anything else (implementation details) should not be in
                                std. At least that's my reading on this :-)

                                However we've gotten off topic, I still think that the original suggestion
                                - importing global symbols into namespace std for VC6 is the right way to
                                go.

                                - John.
                              • Beman Dawes
                                ... suggestion ... way to ... Agreed. I will try to post the changes to config.hpp today or tomorrow. --Beman
                                Message 15 of 26 , Oct 11, 1999
                                  John Maddock wrote:

                                  > [interesting discussion of hiding implementations in
                                  > undocumented namespaces...]
                                  >
                                  >However we've gotten off topic, I still think that the original
                                  suggestion
                                  >- importing global symbols into namespace std for VC6 is the right
                                  way to
                                  >go.

                                  Agreed. I will try to post the changes to config.hpp today or
                                  tomorrow.

                                  --Beman
                                Your message has been successfully submitted and would be delivered to recipients shortly.