From: Nicolas B. <nic...@en...> - 2008-03-07 17:33:13
|
mundy@le... wrote: > I do wonder about adopting boost smart pointers vs. the existing vxl > smart pointer. Is there a big advantage to Boost's smart pointer? I've just noticed an important difference between them: Boost smart pointers are thread-safe. They implement a very efficient locking mechanism that ensures thread-safe reference counting. This is unfortunately not the case in vxl :-( |
From: Amitha P. <ami...@us...> - 2008-03-07 19:08:41
|
Nicolas Burrus wrote: > I've just noticed an important difference between them: Boost smart > pointers are thread-safe. They implement a very efficient locking > mechanism that ensures thread-safe reference counting. This is > unfortunately not the case in vxl :-( In the last t-con, there was a plan to import tr1 into vcl. tr1 includes the smart pointers, so "real soon now", we should be able to move from vbl_smart_ptr to vcl_shared_ptr (and weak_ptr, and so on). Amitha. |
From: Matt L. <mat...@gm...> - 2008-03-07 19:30:05
|
VXL maintainers, At the last VXL teleconference in January I volunteered to look into Boost smart pointers and how they could be imported into vcl. I have to admit that I haven't had time to investigate how or if they should be incorporated into VXL, but I did spend some time reading about the Boost Smart Pointer library. So here is a quick synopsis of points that are relevant to the last discussion on this topic: 1) Boost has several different smart pointers: scoped_ptr, shared_ptr, weak_ptr, intrusive_ptr, and some version of these for arrays. In summary: a) scoped_ptr is a very basic, single owner pointer (e.g. for use in pimpl), not very relevant to this discussion b) shared_ptr is a sharing pointer that does not require the object to keep it's own reference count. There is no need for a ref_count base class as used with the vbl_smart_pointer (e.g. shared_ptr<int> is perfectly valid) c) weak_ptr is the dumb pointer counterpart to shared_ptr to break cycles. You can't use raw pointers for this because the ref count is not kept in the object. d) intrusive_ptr is very similar to vbl_smart_pointer in concept. 2) I've noticed that in vbl we have vbl_scoped_ptr and vbl_shared_ptr. As far as I can tell, these are not based on the Boost code (unless maybe an old version of it), but may have similar function. 3) We decided that we only want to import parts of Boost that are in C++0x TR1 (i.e. set to be part of the next C++ standard). The only Boost smart pointers I see in TR1 are shared_ptr and weak_ptr. 4) Thread safety: "shared_ptr objects offer the same level of thread safety as built-in types." I assume this applies to weak_ptr too. 5) These pointers seems to be exception safe, but I'm not all that familiar with exceptions so maybe someone else can verify this. It seems like bringing shared_ptr and weak_ptr into vcl is good plan. I think most smart pointer use in VXL can be transitioned over time to use these classes. I think the easy of used of shared_ptr and thread safety outweigh the slight performance hit over an intrusive pointer, but we can always keep vbl_smart_pointer around for the cases where this is important. If I can find some time, and no one objects, I will try to bring these two classes into vcl. I may need some guidance since I have never touched vcl internals before. We are still sticking to the vcl_ prefix correct? So these would be vcl_shared_ptr and vcl_weak_ptr? --Matt On Fri, Mar 7, 2008 at 12:33 PM, Nicolas Burrus <nic...@en...> wrote: > mundy@le... wrote: > > I do wonder about adopting boost smart pointers vs. the existing vxl > > smart pointer. Is there a big advantage to Boost's smart pointer? > > I've just noticed an important difference between them: Boost smart > pointers are thread-safe. They implement a very efficient locking > mechanism that ensures thread-safe reference counting. This is > unfortunately not the case in vxl :-( > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > Vxl-maintainers mailing list > Vxl...@li... > https://lists.sourceforge.net/lists/listinfo/vxl-maintainers > |
From: Amitha P. <ami...@us...> - 2008-03-07 22:09:30
|
Matt Leotta wrote: > We are still sticking to the vcl_ > prefix correct? So these would be vcl_shared_ptr and vcl_weak_ptr? I think they should be. Technically, they'd be in the std::tr1 namespace, but vcl should gloss over that. My thought is that, in the vcl way, if std::tr1::shared_ptr exists[*], then vcl_shared_ptr should be a #define to that. Otherwise, it'll fall back to a boost-based implementation. I'd be willing to help. Amitha. [*] It does exist on many compilers. For example, g++ 4.1.3 has it. (And it happens to be a boost based implementation.) |
From: Peter V. <pet...@ya...> - 2008-03-08 19:23:31
|
--- Matt Leotta wrote: > b) shared_ptr is a sharing pointer that does not require the > object to keep its own reference count. Do I understand this correctly that the ref-count is kept in the pointer itself? Or is there no ref-count at all, in which case the base object's destructor is never called? That would undermine the whole concept of smart pointers, I would think. -- Peter. -- __________________________________________________________ Går det långsamt? Skaffa dig en snabbare bredbandsuppkoppling. Sök och jämför hos Yahoo! Shopping. http://shopping.yahoo.se/c-100015813-bredband.html?partnerId=96914325 |
From: Nicolas B. <nic...@en...> - 2008-03-08 19:52:24
|
On Sat, Mar 8, 2008 at 8:23 PM, Peter Vanroose <pet...@ya...> wrote: > --- Matt Leotta wrote: > > > b) shared_ptr is a sharing pointer that does not require the > > object to keep its own reference count. > > Do I understand this correctly that the ref-count is kept in the > pointer itself? > Or is there no ref-count at all, in which case the base object's > destructor is never called? That would undermine the whole concept > of smart pointers, I would think. Yes, the ref-count is kept in the shared_ptr class. Thus, it is not intrusive, but requires a systematic use of shared_ptr<T> instead of T*. |
From: Matt L. <mat...@gm...> - 2008-03-10 17:27:04
|
Looking at the TR1, it seems that shared_ptr and weak_ptr are destined to be added to the <memory> include file. Currently, if you have tr1 support for gcc, you need to include <tr1/boost_shared_ptr>. My guess is that this path is specific to gcc. Should it be the case that we add the definitions for vcl_shared_ptr (and vcl_weak_ptr) to <vcl_memory.h> or should there be a new file like <vcl_shared_ptr.h>? Also, I'm assuming I need to create some sort of CMake compiler test to see if shared_ptr exists on the system. I'm not sure where to begin with this. I figured I would model this after VCL_USE_NATIVE_STL, but I can't even find where that CMake variable is defined. Can anyone point me in the right direction? Thanks, Matt On Fri, Mar 7, 2008 at 6:09 PM, Amitha Perera <ami...@us...> wrote: > Matt Leotta wrote: > > We are still sticking to the vcl_ > > prefix correct? So these would be vcl_shared_ptr and vcl_weak_ptr? > > I think they should be. Technically, they'd be in the std::tr1 > namespace, but vcl should gloss over that. > > My thought is that, in the vcl way, if std::tr1::shared_ptr exists[*], > then vcl_shared_ptr should be a #define to that. Otherwise, it'll fall > back to a boost-based implementation. > > I'd be willing to help. > > Amitha. > > [*] It does exist on many compilers. For example, g++ 4.1.3 has it. > (And it happens to be a boost based implementation.) > > |
From: Amitha P. <ami...@us...> - 2008-03-11 14:45:29
|
Matt Leotta wrote: > Looking at the TR1, it seems that shared_ptr and weak_ptr are > destined to be added to the <memory> include file. I think we should look beyond tr1 to the 0x standard. Draft: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2135.pdf > Currently, if you > have tr1 support for gcc, you need to include <tr1/boost_shared_ptr>. Actually, I think one is meant to include <tr1/memory>. > Should it be the case > that we add the definitions for vcl_shared_ptr (and vcl_weak_ptr) to > <vcl_memory.h> or should there be a new file like <vcl_shared_ptr.h>? They should go into vcl_memory.h, to match where they will be in the next standard. > Also, I'm assuming I need to create some sort of CMake compiler test > to see if shared_ptr exists on the system. I'm not sure where to > begin with this. The platform tests are in config/cmake/config/vxl_platform_tests.cxx. I think the way forward is: - Define the new entries in vcl/generic/vcl_memory.hhh, etc, and run the generate script to get the iso entries. - For compilers like gcc, do e.g. #include <tr1/memory> before #include "iso/vcl_memory.h" - For others, maybe #include <boost/shared_ptr.h> or <emulation/shared_ptr.h> that'll define a std::shared_ptr? Consider this a draft approach. The details will have to be ironed out as its done. The main goal, however, is that the user will be able to include vcl_memory.h and use vcl_shared_ptr without worry. (I'm willing to t-con with anyone who wants to discuss this over the phone.) Amitha. |
From: Matt L. <mat...@gm...> - 2008-03-11 20:06:03
|
On Tue, Mar 11, 2008 at 10:45 AM, Amitha Perera <ami...@us...> wrote: > I think we should look beyond tr1 to the 0x standard. Draft: > > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2135.pdf Alright, fine with me. Thanks for the link. > > Currently, if you > > have tr1 support for gcc, you need to include <tr1/boost_shared_ptr>. > > Actually, I think one is meant to include <tr1/memory>. I didn't notice that <tr1/memory> includes <tr1/boost_shared_ptr>. You are right, it's clear from the standard that <tr1/memory> should be included. > The platform tests are in config/cmake/config/vxl_platform_tests.cxx. I > think the way forward is: > - Define the new entries in vcl/generic/vcl_memory.hhh, etc, and run the > generate script to get the iso entries. > - For compilers like gcc, do e.g. #include <tr1/memory> before #include > "iso/vcl_memory.h" > - For others, maybe #include <boost/shared_ptr.h> or > <emulation/shared_ptr.h> that'll define a std::shared_ptr? > I've got a slightly better understanding of how vcl works now. I've added the smart pointer stuff from the standard in vcl/generic/vcl_memory.hhh (in my local copy). I've got a basic platform check working that looks for shared_ptr<void> first in <memory> and then in <tr1/memory>. If found in tr1 I include <tr1/memory> before "iso/vcl_memory", but I also have to do some namespace mapping: namespace std{ using namespace std::tr1; } I plan to add "emulation/shared_ptr.h" for those platforms that don't have any implementation. I'll probably take this directly from gcc for the moment. I'll check this all in when I get something basic working. I expect the emulation version won't work right away. > (I'm willing to t-con with anyone who wants to discuss this over the phone.) I'm willing to do this too. On another topic, I think this would all be much cleaner if vcl_ was replaced with namespace vcl. I don't have time to work on this conversion right now, but it seems that this might be a good place to start with introducing namespaces to VXL. We could leave the rest of the prefixes (vil_, vnl_, etc.) for now and simply replace vcl_ with vcl::. I'll add this to my list of things to look into if there is ever free time (which is probably not for a long time). --Matt |
From: Brad K. <bra...@ki...> - 2008-03-11 21:43:02
|
Matt Leotta wrote: > I've got a slightly better understanding of how vcl works now. I've > added the smart pointer stuff from the standard in > vcl/generic/vcl_memory.hhh (in my local copy). I've got a basic > platform check working that looks for shared_ptr<void> first in > <memory> and then in <tr1/memory>. If found in tr1 I include > <tr1/memory> before "iso/vcl_memory", but I also have to do some > namespace mapping: > > namespace std{ > using namespace std::tr1; > } > > I plan to add "emulation/shared_ptr.h" for those platforms that don't > have any implementation. I'll probably take this directly from gcc > for the moment. I'll check this all in when I get something basic > working. I expect the emulation version won't work right away. The vcl_ macros should just be defined to point at the symbols inside the tr1 namespace. There should be no using declarations or using directives in vcl. >> (I'm willing to t-con with anyone who wants to discuss this over the phone.) > I'm willing to do this too. > > On another topic, I think this would all be much cleaner if vcl_ was > replaced with namespace vcl. I don't have time to work on this > conversion right now, but it seems that this might be a good place to > start with introducing namespaces to VXL. We could leave the rest of > the prefixes (vil_, vnl_, etc.) for now and simply replace vcl_ with > vcl::. I'll add this to my list of things to look into if there is > ever free time (which is probably not for a long time). We cannot do that. The whole point of having vcl_ instead of vcl:: is to allow every single symbol to be defined as a macro independently without polluting the macro namespace. -Brad |
From: Matt L. <mat...@gm...> - 2008-03-12 00:40:23
|
Brad, On Tue, Mar 11, 2008 at 5:43 PM, Brad King <bra...@ki...> wrote: > The vcl_ macros should just be defined to point at the symbols inside > the tr1 namespace. There should be no using declarations or using > directives in vcl. This makes things much more difficult. The setup of the main vcl directories as I understand it is: iso - contains script generated files to include an iso standard header (i.e. #include <memory>), define the working namespace (i.e. #define vcl_generic_memory_STD std), and then include the vcl generic header to define std::* to vcl_* generic - contains script generated files to define a set of standard symbols from a common namespace to vcl_ prefixed (i.e. #define vcl_auto_ptr vcl_generic_memory_STD :: auto_ptr) emulation - provide implementations from scratch of vcl_ symbols when std is not available The situation we have is a set a existing iso files (for example, <memory>) for which most compilers come with ISO standard implementations. In this case, vcl should include iso/vcl_memory.h. But now we want to augment vcl_memory.h with symbols part of the new c++ standard. Some compilers already provide these symbol (and we want to use them), but they are in a different namespace (std::tr1). Other compilers don't provide them at all, and still other (some day) will provide them in std. So we have to deal with all cases: 1) All symbols defined in <memory> (namespace std) 2) Some symbols defined in <memory> (namespace std), some symbols defined in <tr1/memory> (namespace std::tr1) 3) Some symbols defined in <memory> (namespace std), some symbols not defined (use partial emulation) 4) No symbols defined (use emulation) The real problem is the use of two namespaces, since the code in the generic directory expects a single namespace to be defined for all symbols in a given header. My solution was to bring std:tr1 into std before defining these macros. Could you explain why this is bad and how to properly solve this within the vcl framework? In general there could be name clashes but since tr1 contains additions to std that will be moving into std, this shouldn't happen. > > We cannot do that. The whole point of having vcl_ instead of vcl:: is > to allow every single symbol to be defined as a macro independently > without polluting the macro namespace. Could you elaborate on this? What exactly is the macro namespace? Why does every symbol have to be a macro? And why can we not create a vcl namespace and populate it with std and emulated code in a platform specific way? Thanks, Matt |
From: Brad K. <bra...@ki...> - 2008-03-12 04:36:17
|
Matt Leotta wrote: > Could you explain why this is bad and > how to properly solve this within the vcl framework? I think Amitha's answer is sufficient. >> We cannot do that. The whole point of having vcl_ instead of vcl:: is >> to allow every single symbol to be defined as a macro independently >> without polluting the macro namespace. > > Could you elaborate on this? What exactly is the macro namespace? I mean the table of macro names maintained by the preprocessor. We don't want to ever write #define shared_ptr tr1::shared_ptr or something like that. The names of all macros should begin in vcl_ to avoid possible clashes with system or user macros. > Why does every symbol have to be a macro? If they are all to start with vcl_ then most symbols have to be a macro to map to the proper native namespace name. The reason we want everything to start in vcl_ is to allow any combination of macros and emulated names with a consistent user syntax. > And why can we not create a vcl > namespace and populate it with std and emulated code in a platform > specific way? The idea of vcl is to translate directly to standard code for conforming compilers. If we created a vcl namespace for all the standard symbols, then vcl_iostream.h for example would have to be something like #include <iostream> namespace vcl { using std::ostream; using std::istream; using std::cout; // ... } even for conforming compilers. For non-conforming compilers using declarations are not necessarily reliable. The macros can map directly to std:: names on conforming compilers and be defined as needed for non-conforming compilers. This has worked well for many years. It is tempting to write namespace vcl { using namespace std; } However, this would make it impossible to selectively replace broken system implementations with corrected emulation code. Additionally, one of the things I like about using vcl is that the macros for particlar names are defined only in the proper vcl headers. The vcl headers do not transitively include other vcl headers (at least not often). This means that programs using the headers need to explicitly include all the headers they need. When using straight std:: many compilers' standard headers include each other so one may end up with code that uses a symbol for which the proper header has not been directly included. The vcl approach helps avoid this problem. -Brad |
From: Matt L. <mat...@gm...> - 2008-03-12 13:12:17
|
Brad, Thanks for the clarifications. On Wed, Mar 12, 2008 at 12:36 AM, Brad King <bra...@ki...> wrote: > Matt Leotta wrote: > > And why can we not create a vcl > > namespace and populate it with std and emulated code in a platform > > specific way? > > The idea of vcl is to translate directly to standard code for conforming > compilers. If we created a vcl namespace for all the standard symbols, > then vcl_iostream.h for example would have to be something like > > #include <iostream> > namespace vcl > { > using std::ostream; > using std::istream; > using std::cout; > // ... > } This is exactly the sort of thing I had in mind. > > even for conforming compilers. For non-conforming compilers using > declarations are not necessarily reliable. The macros can map directly > to std:: names on conforming compilers and be defined as needed for > non-conforming compilers. This has worked well for many years. > It seems this issue of conforming compilers (with respect to namespaces) is the key issue. Are there really still compilers supported by VXL that do not properly implement namespaces? Namespaces have been part of the C++ standard for 10 years. Which compilers are still non-conforming? > > Additionally, one of the things I like about using vcl is that the > macros for particlar names are defined only in the proper vcl headers. > The vcl headers do not transitively include other vcl headers (at least > not often). This means that programs using the headers need to > explicitly include all the headers they need. When using straight std:: > many compilers' standard headers include each other so one may end up > with code that uses a symbol for which the proper header has not been > directly included. The vcl approach helps avoid this problem. > This is a good point, but I don't see why the same thing isn't possible with a vcl namespace instead of vcl macros. Just to be clear, I don't see any reason we need to move away from the current vcl system of macros. I just want to understand the reasons why namespace solution is not a viable alternative. I certainly do not have the time to implement a namespace version of vcl, but if there are no compelling reasons why it wouldn't work, then maybe it's something to leave open for the future. --Matt |
From: Brad K. <bra...@ki...> - 2008-03-12 13:32:02
|
Matt Leotta wrote: >> #include <iostream> >> namespace vcl >> { >> using std::ostream; >> using std::istream; >> using std::cout; >> // ... >> } > > This is exactly the sort of thing I had in mind. Good. It would actually be pretty cool. Actually, it could coexist with the vcl_ macros. If we were ever to change over to this approach the vcl_ macros would all have to be available for compatibility with existing code. They could just point into the vcl:: namespace. >> even for conforming compilers. For non-conforming compilers using >> declarations are not necessarily reliable. The macros can map directly >> to std:: names on conforming compilers and be defined as needed for >> non-conforming compilers. This has worked well for many years. > > It seems this issue of conforming compilers (with respect to > namespaces) is the key issue. Are there really still compilers > supported by VXL that do not properly implement namespaces? > Namespaces have been part of the C++ standard for 10 years. Which > compilers are still non-conforming? The old HP compiler and VS 6 and 7.0 all have trouble with name lookup rules and using declarations IIRC. I don't know if vxl still cares about these compilers though. >> Additionally, one of the things I like about using vcl is that the >> macros for particlar names are defined only in the proper vcl headers. >> The vcl headers do not transitively include other vcl headers (at least >> not often). This means that programs using the headers need to >> explicitly include all the headers they need. When using straight std:: >> many compilers' standard headers include each other so one may end up >> with code that uses a symbol for which the proper header has not been >> directly included. The vcl approach helps avoid this problem. > > This is a good point, but I don't see why the same thing isn't > possible with a vcl namespace instead of vcl macros. It is possible, just not with the "using namespace std" approach. -Brad |
From: Amitha P. <ami...@us...> - 2008-03-12 14:02:16
|
Brad King wrote: > The old HP compiler and VS 6 and 7.0 all have trouble with name lookup > rules and using declarations IIRC. I don't know if vxl still cares > about these compilers though. vxl doesn't care about them directly, but we care about other projects using (parts of) vxl that care. My stance is that we care to the degree that we can move forward reasonably while continuing to support those projects. I don't think vxl-maintainers has ever come to a definite statement about it, though. Amitha. |
From: Ian S. <ian...@st...> - 2008-03-12 14:25:00
|
Matt, Two points. 1. The more core the part of VXL the older compilers it supports. Mostly that is because of ITK using VNL. However the general rule still applies - and vcl is the most core code of all. The original rational was to keep VXL useful for embedded systems with poor compilers. Whilst we haven't released any products for embedded systems we have done some engineering work in support of business cases. We came to the conclusion that we (Imorphics) would always need a large embedded system with a full scale memory manager, and file-system in the OS, and at least a few 100Mb memory - i.e. in all the ways that matter - a proper hosted C++ implementation on a PC/workstation. So we are less worried about support for lightweight embedded systems, and would be happy to see the C++ compiler requirements strengthened. 2. If you are going to commit your existing work, you might think of putting it on a repository branch. In hindsight I wish now that we had committed our experimental VNL_SSE stuff as a branch. It is time consuming to accurately separate off something this invasive with code exclusion macros, and still maintain a fully working system. The unfinished code sometimes confuses other people who are trying to read code/solve problems in the affected files but really don't care yet about your additions. I really appreciate the work you are putting into this. It will be great to have tr1 in vcl - thanks. Ian. Brad King wrote: > Matt Leotta wrote: >>> #include <iostream> >>> namespace vcl >>> { >>> using std::ostream; >>> using std::istream; >>> using std::cout; >>> // ... >>> } >> This is exactly the sort of thing I had in mind. > > Good. It would actually be pretty cool. Actually, it could coexist > with the vcl_ macros. If we were ever to change over to this approach > the vcl_ macros would all have to be available for compatibility with > existing code. They could just point into the vcl:: namespace. > >>> even for conforming compilers. For non-conforming compilers using >>> declarations are not necessarily reliable. The macros can map directly >>> to std:: names on conforming compilers and be defined as needed for >>> non-conforming compilers. This has worked well for many years. >> It seems this issue of conforming compilers (with respect to >> namespaces) is the key issue. Are there really still compilers >> supported by VXL that do not properly implement namespaces? >> Namespaces have been part of the C++ standard for 10 years. Which >> compilers are still non-conforming? > > The old HP compiler and VS 6 and 7.0 all have trouble with name lookup > rules and using declarations IIRC. I don't know if vxl still cares > about these compilers though. > >>> Additionally, one of the things I like about using vcl is that the >>> macros for particlar names are defined only in the proper vcl headers. >>> The vcl headers do not transitively include other vcl headers (at least >>> not often). This means that programs using the headers need to >>> explicitly include all the headers they need. When using straight std:: >>> many compilers' standard headers include each other so one may end up >>> with code that uses a symbol for which the proper header has not been >>> directly included. The vcl approach helps avoid this problem. >> This is a good point, but I don't see why the same thing isn't >> possible with a vcl namespace instead of vcl macros. > > It is possible, just not with the "using namespace std" approach. > > -Brad > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > Vxl-maintainers mailing list > Vxl...@li... > https://lists.sourceforge.net/lists/listinfo/vxl-maintainers |
From: Matt L. <mat...@gm...> - 2008-03-12 15:29:50
|
Thanks for the feedback everyone. I'm not sure if I want to deal with branching VXL right now. For now, this C++0x stuff will be an experimental and optional addition to vcl (enabled by CMake). I think the code should be restricted to vcl and vcl/tests until we are confident that it works across all platforms. It should not be used to replace any existing code in the rest of vxl (i.e. vbl_smart_pointer). When we are ready to start using this code in other vxl libraries, maybe that would be the time to make a branch. I plan to follow Amitha's suggestion and define VCL_INCLUDE_CXX_0X as a CMake option with the default value of ${VXL_BUILD_FOR_DASHBOARD}. This way it will show up on dashboard builds, but not effect normal users. I am still running into one problem. In vcl/generic/vcl_memory.hhh there is no way to optionally disable a subset of symbols. I could temporarily violate the rules and manually modify the generated file vcl/generic/vcl_memory.h, but this is not a good solution. The vcl/generic/zap.pl script is quite simple and it needs to be generalized. Yes, I am playing the "I need to graduate" card, so I can't afford to make a major revision to vcl right now. Another solution is to create a second file like generic/vcl_memory_0x.hhh and a corresponding iso/vcl_memory_0x.h. This doesn't seem right either because the files in iso are supposed to represent real ISO standard files. Suggestions? --Matt On Wed, Mar 12, 2008 at 10:23 AM, Ian Scott <ian...@st...> wrote: > Matt, > > Two points. > > 1. The more core the part of VXL the older compilers it supports. Mostly > that is because of ITK using VNL. However the general rule still applies > - and vcl is the most core code of all. > The original rational was to keep VXL useful for embedded systems with > poor compilers. Whilst we haven't released any products for embedded > systems we have done some engineering work in support of business cases. > We came to the conclusion that we (Imorphics) would always need a large > embedded system with a full scale memory manager, and file-system in the > OS, and at least a few 100Mb memory - i.e. in all the ways that matter - > a proper hosted C++ implementation on a PC/workstation. So we are less > worried about support for lightweight embedded systems, and would be > happy to see the C++ compiler requirements strengthened. > > 2. If you are going to commit your existing work, you might think of > putting it on a repository branch. In hindsight I wish now that we had > committed our experimental VNL_SSE stuff as a branch. It is time > consuming to accurately separate off something this invasive with code > exclusion macros, and still maintain a fully working system. The > unfinished code sometimes confuses other people who are trying to read > code/solve problems in the affected files but really don't care yet > about your additions. > > I really appreciate the work you are putting into this. It will be great > to have tr1 in vcl - thanks. > > Ian. > > > > > Brad King wrote: > > Matt Leotta wrote: > >>> #include <iostream> > >>> namespace vcl > >>> { > >>> using std::ostream; > >>> using std::istream; > >>> using std::cout; > >>> // ... > >>> } > >> This is exactly the sort of thing I had in mind. > > > > Good. It would actually be pretty cool. Actually, it could coexist > > with the vcl_ macros. If we were ever to change over to this approach > > the vcl_ macros would all have to be available for compatibility with > > existing code. They could just point into the vcl:: namespace. > > > >>> even for conforming compilers. For non-conforming compilers using > >>> declarations are not necessarily reliable. The macros can map directly > >>> to std:: names on conforming compilers and be defined as needed for > >>> non-conforming compilers. This has worked well for many years. > >> It seems this issue of conforming compilers (with respect to > >> namespaces) is the key issue. Are there really still compilers > >> supported by VXL that do not properly implement namespaces? > >> Namespaces have been part of the C++ standard for 10 years. Which > >> compilers are still non-conforming? > > > > The old HP compiler and VS 6 and 7.0 all have trouble with name lookup > > rules and using declarations IIRC. I don't know if vxl still cares > > about these compilers though. > > > >>> Additionally, one of the things I like about using vcl is that the > >>> macros for particlar names are defined only in the proper vcl headers. > >>> The vcl headers do not transitively include other vcl headers (at least > >>> not often). This means that programs using the headers need to > >>> explicitly include all the headers they need. When using straight std:: > >>> many compilers' standard headers include each other so one may end up > >>> with code that uses a symbol for which the proper header has not been > >>> directly included. The vcl approach helps avoid this problem. > >> This is a good point, but I don't see why the same thing isn't > >> possible with a vcl namespace instead of vcl macros. > > > > It is possible, just not with the "using namespace std" approach. > > > > -Brad > > > > > > ------------------------------------------------------------------------- > > This SF.net email is sponsored by: Microsoft > > Defy all challenges. Microsoft(R) Visual Studio 2008. > > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > > _______________________________________________ > > Vxl-maintainers mailing list > > Vxl...@li... > > https://lists.sourceforge.net/lists/listinfo/vxl-maintainers > > |
From: Brad K. <bra...@ki...> - 2008-03-12 15:39:36
|
Matt Leotta wrote: > I am still running into one problem. In vcl/generic/vcl_memory.hhh > there is no way to optionally disable a subset of symbols. I could > temporarily violate the rules and manually modify the generated file > vcl/generic/vcl_memory.h, but this is not a good solution. The > vcl/generic/zap.pl script is quite simple and it needs to be > generalized. Yes, I am playing the "I need to graduate" card, so I > can't afford to make a major revision to vcl right now. Another > solution is to create a second file like generic/vcl_memory_0x.hhh and > a corresponding iso/vcl_memory_0x.h. This doesn't seem right either > because the files in iso are supposed to represent real ISO standard > files. Suggestions? Create a tr1/vcl_memory.h which includes iso/vcl_memory.h and then adds the new symbols. When tr1 support is enabled include the former and otherwise the latter. -Brad |
From: Matt L. <mat...@gm...> - 2008-03-12 16:01:11
|
Brad, On Wed, Mar 12, 2008 at 11:37 AM, Brad King <bra...@ki...> wrote: > Matt Leotta wrote: > > I am still running into one problem. In vcl/generic/vcl_memory.hhh > > there is no way to optionally disable a subset of symbols. I could > > temporarily violate the rules and manually modify the generated file > > vcl/generic/vcl_memory.h, but this is not a good solution. The > > vcl/generic/zap.pl script is quite simple and it needs to be > > generalized. Yes, I am playing the "I need to graduate" card, so I > > can't afford to make a major revision to vcl right now. Another > > solution is to create a second file like generic/vcl_memory_0x.hhh and > > a corresponding iso/vcl_memory_0x.h. This doesn't seem right either > > because the files in iso are supposed to represent real ISO standard > > files. Suggestions? > > Create a tr1/vcl_memory.h which includes iso/vcl_memory.h and then adds > the new symbols. When tr1 support is enabled include the former and > otherwise the latter. iso/vcl_memory.h includes generic/vcl_memory.h which is where the real problem is. What would tr1/vcl_memory.h include? I could certainly use tr1/vcl_memory.h to manually make the definitions, but I thought it be best to follow the vcl way and make all definitions in generic/. Maybe I also need generic/tr1/vcl_memory.hhh? Also, since we are looking beyond tr1 to the new standard, is tr1 an appropriate name for this? As you can see, this more of a problem with following standards in vcl. There are many ways to get it working, but which way is most in line with vcl and most appropriate going forward? Thanks, Matt |
From: Brad K. <bra...@ki...> - 2008-03-12 16:12:07
|
Matt Leotta wrote: > On Wed, Mar 12, 2008 at 11:37 AM, Brad King <bra...@ki...> wrote: >> Create a tr1/vcl_memory.h which includes iso/vcl_memory.h and then adds >> the new symbols. When tr1 support is enabled include the former and >> otherwise the latter. > > iso/vcl_memory.h includes generic/vcl_memory.h which is where the real > problem is. What would tr1/vcl_memory.h include? I could certainly > use tr1/vcl_memory.h to manually make the definitions, but I thought > it be best to follow the vcl way and make all definitions in generic/. > Maybe I also need generic/tr1/vcl_memory.hhh? Also, since we are > looking beyond tr1 to the new standard, is tr1 an appropriate name for > this? > > As you can see, this more of a problem with following standards in > vcl. There are many ways to get it working, but which way is most in > line with vcl and most appropriate going forward? Since none of these files are meant for direct inclusion by user code I don't think it matters. Until we know the "X" in "0X" we should probably avoid making a directory for it. Until we make a directory for it we don't need to finalize the design. I think you can just add some files (vcl_memory_tr1.h or something) by hand for now. -Brad |
From: Amitha P. <ami...@us...> - 2008-03-12 03:04:49
|
Brad King wrote: > The vcl_ macros should just be defined to point at the symbols inside > the tr1 namespace. There should be no using declarations or using > directives in vcl. I agree with this. The problem with doing things like "using namespace std::tr1", even into the std namespace, is that it introduces symbols into that namespace that didn't exist before. This could cause downstream errors, such as ambiguous overloads or symbol conflicts. Consider, for example, #include <memory> using namespace std; class shared_ptr { ... }; // my own class This works fine right now, but would break if std::tr1 was folded into std. So, as Brad suggests, we should have something like #if VCL_HAS_STD_SHARED_PTR # define vcl_shared_sptr std::shared_ptr #elif VCL_HAS_TR1_SHARED_PTR # define vcl_shared_sptr std::tr1::shared_ptr #else # include "emulation/shared_ptr.h" #endif Of course, it does mean more work for the library maintainer, but results in much happier users. However it's not yet clear (to me at least) what the cleanest way is to generalize this to all the symbols in tr1 and C++0x. Amitha. |
From: Matt L. <mat...@gm...> - 2008-03-12 12:13:12
|
Amitha, On Tue, Mar 11, 2008 at 6:50 PM, Amitha Perera <ami...@us...> wrote: > Brad King wrote: > > The vcl_ macros should just be defined to point at the symbols inside > > the tr1 namespace. There should be no using declarations or using > > directives in vcl. > > I agree with this. The problem with doing things like "using namespace > std::tr1", even into the std namespace, is that it introduces symbols > into that namespace that didn't exist before. This could cause > downstream errors, such as ambiguous overloads or symbol conflicts. > Consider, for example, > > #include <memory> > using namespace std; > class shared_ptr { ... }; // my own class > > This works fine right now, but would break if std::tr1 was folded into std. True, but this is always the case when using a namespace. For example, #include <vector> using namespace std; class vector { ... }; // my own class This will break because vector is in std. I think the lesson here is avoid "using namespace" unless you are prepared to deal with name clashes. As I see it, tr1 will eventually be folded into std by the compiler vendors, so you will eventually get the same errors in your code. I'm not arguing that namespace folding is an appropriate solution in vcl. In fact, it's clear that conditionally defined macros are the appropriate way in vcl. However, I am wondering if I should commit my change as a temporary solution. > So, as Brad suggests, we should have something like > > #if VCL_HAS_STD_SHARED_PTR > # define vcl_shared_sptr std::shared_ptr > #elif VCL_HAS_TR1_SHARED_PTR > # define vcl_shared_sptr std::tr1::shared_ptr > #else > # include "emulation/shared_ptr.h" > #endif > > Of course, it does mean more work for the library maintainer, but > results in much happier users. However it's not yet clear (to me at > least) what the cleanest way is to generalize this to all the symbols in > tr1 and C++0x. I agree, I think that the scripted vcl setup we have now needs to be generalized somehow in order to handle this appropriately. Unfortunately, I don't have the time for this. I need to spend some time on my thesis if I ever want to get out of grad school. I can commit what I have (with the namespace folding hack) if someone is willing to pick it up and provide a proper vcl solution. --Matt |
From: Amitha P. <ami...@us...> - 2008-03-12 13:58:00
|
Matt Leotta wrote: > True, but this is always the case when using a namespace. For example, > > #include <vector> > using namespace std; > class vector { ... }; // my own class > > This will break because vector is in std. [...] > As I see it, tr1 will eventually be folded into std by the > compiler vendors, so you will eventually get the same errors in your > code. Fair enough. However, most compilers will likely have a magic "leave me with c++98" flag for backward compatibility. Perhaps this is the solution to take: put in a VCL_INCLUDE_C_PLUS_PLUS_0X define, and only do the tr1 magic if this is true. In this case, folding tr1 into std (not beyond that) is okay, because c++0x will have the symbols in std anyway. > However, I am wondering if I should commit my > change as a temporary solution. Why don't you do ahead and commit, and try to get the dashboard green? I'd suggest a quick email to vxl-users as a heads-up, for those users that use CVS vxl. If that magic flag is available (settable at CMake time, too), that'll make it easier for folks. > I need to spend some > time on my thesis if I ever want to get out of grad school. Sigh. You had to play the "but I need to graduate" card. :-) > I can > commit what I have (with the namespace folding hack) if someone is > willing to pick it up and provide a proper vcl solution. Do what you can, preferably getting it working on the dashboard machines, and I'll take it from there. I have to work out a clean way of getting the threading in there too. (Though boost::thread is different from c++0x thread). Amitha. |
From: Amitha P. <ami...@us...> - 2008-03-12 17:57:43
|
Matt, In the interest of getting things rolling *and* you graduating, I think it'd be okay to have a manual, semi-automatic, or automatic solution. I think the experience in getting that to work on all the platforms will tell us a lot about how we can and cannot approach the full generic solution. I (and perhaps others) can take it from there. A clean, default "off" for the feature would make a branch unnecessary. Moreover, I think a branch in this case will be counter-productive, because we won't be able to use the dashboard to test all the different OS/compiler combinations. If you could also document failures, and outline your thoughts on how it should or could be done generically, that'll help when I pick up from where you leave off. Amitha. |
From: Matt L. <mat...@gm...> - 2008-03-12 20:48:41
|
I'm happy to report that I have a working solution to the renaming problem (thanks to all of your suggestions). It also avoids the issue of folding std::tr1 into std. Here is a summary: vcl/generic contains vcl_blah.hhh (for old symbols) and vcl_blah_tr1.hhh (for new symbols). These generate the .h files. vcl/iso contains vcl_blah.h (which includes <blah> and "generic/vcl_blah.h" and refers to namespace std) and vcl_blah_tr1.h (which includes <blah> and "generic/vcl_blah_tr1.h" and refers to namespace std) vcl/tr1 contains vcl_blah.h (which includes <tr1/blah> and "generic/vcl_blah_tr1.h" and refers to namespace std::tr1) for ISO compilers the top level vcl_blah.h does the following: #include "iso/vcl_blah.h" #if VCL_INCLUDE_CXX_0X # if VCL_BLAH_HAS_0X # include "iso/vcl_blah_tr1.h" # elif VCL_BLAH_HAS_TR1 # include "tr1/vcl_blah.h" # else # include "emulation/vcl_files_to_emulate_blah_0x.h" # endif #endif Now the only problem is how to emulate shared_ptr. This is much more complicated than I originally thought. The gcc implementation is dependent on a lot of gcc internals (like namespace __gnu_cxx). The Boost implementation is dependent on a LARGE base of Boost code for cross platform compatibility. Obviously vcl duplicates a portion of this, but vcl-ifying Boost will not be trivial, even for a single class like shared_ptr. We could probably write a simplified version that drops all of the exception and thread safety handling, but even this would be a big project. Any suggestions on how to handle this? Thanks, Matt P.S. below is a list of all Boost files that boost/shared_ptr.hpp depends on (recursively) boost/assert.hpp boost/checked_delete.hpp boost/config.hpp boost/config/no_tr1/utility.hpp boost/config/posix_features.hpp boost/config/select_compiler_config.hpp boost/config/select_platform_config.hpp boost/config/select_stdlib_config.hpp boost/config/suffix.hpp boost/current_function.hpp boost/detail/atomic_count.hpp boost/detail/atomic_count_gcc.hpp boost/detail/atomic_count_pthreads.hpp boost/detail/atomic_count_win32.hpp boost/detail/bad_weak_ptr.hpp boost/detail/interlocked.hpp boost/detail/lightweight_mutex.hpp boost/detail/lwm_nop.hpp boost/detail/lwm_pthreads.hpp boost/detail/lwm_win32_cs.hpp boost/detail/quick_allocator.hpp boost/detail/shared_count.hpp boost/detail/shared_ptr_nmt.hpp boost/detail/sp_counted_base.hpp boost/detail/sp_counted_base_cw_ppc.hpp boost/detail/sp_counted_base_gcc_ia64.hpp boost/detail/sp_counted_base_gcc_ppc.hpp boost/detail/sp_counted_base_gcc_x86.hpp boost/detail/sp_counted_base_nt.hpp boost/detail/sp_counted_base_pt.hpp boost/detail/sp_counted_base_w32.hpp boost/detail/sp_counted_impl.hpp boost/detail/workaround.hpp boost/mpl/aux_/adl_barrier.hpp boost/mpl/aux_/arity.hpp boost/mpl/aux_/config/adl.hpp boost/mpl/aux_/config/arrays.hpp boost/mpl/aux_/config/ctps.hpp boost/mpl/aux_/config/dtp.hpp boost/mpl/aux_/config/eti.hpp boost/mpl/aux_/config/gcc.hpp boost/mpl/aux_/config/integral.hpp boost/mpl/aux_/config/intel.hpp boost/mpl/aux_/config/lambda.hpp boost/mpl/aux_/config/msvc.hpp boost/mpl/aux_/config/nttp.hpp boost/mpl/aux_/config/overload_resolution.hpp boost/mpl/aux_/config/preprocessor.hpp boost/mpl/aux_/config/static_constant.hpp boost/mpl/aux_/config/ttp.hpp boost/mpl/aux_/config/workaround.hpp boost/mpl/aux_/integral_wrapper.hpp boost/mpl/aux_/lambda_arity_param.hpp boost/mpl/aux_/lambda_support.hpp boost/mpl/aux_/na.hpp boost/mpl/aux_/na_fwd.hpp boost/mpl/aux_/na_spec.hpp boost/mpl/aux_/nttp_decl.hpp boost/mpl/aux_/preprocessor/def_params_tail.hpp boost/mpl/aux_/preprocessor/enum.hpp boost/mpl/aux_/preprocessor/filter_params.hpp boost/mpl/aux_/preprocessor/params.hpp boost/mpl/aux_/preprocessor/sub.hpp boost/mpl/aux_/preprocessor/tuple.hpp boost/mpl/aux_/static_cast.hpp boost/mpl/aux_/template_arity_fwd.hpp boost/mpl/aux_/value_wknd.hpp boost/mpl/aux_/yes_no.hpp boost/mpl/bool.hpp boost/mpl/bool_fwd.hpp boost/mpl/if.hpp boost/mpl/int.hpp boost/mpl/int_fwd.hpp boost/mpl/integral_c.hpp boost/mpl/integral_c_fwd.hpp boost/mpl/integral_c_tag.hpp boost/mpl/lambda_fwd.hpp boost/mpl/limits/arity.hpp boost/mpl/size_t.hpp boost/mpl/size_t_fwd.hpp boost/mpl/void_fwd.hpp boost/non_type.hpp boost/preprocessor/arithmetic/add.hpp boost/preprocessor/arithmetic/dec.hpp boost/preprocessor/arithmetic/inc.hpp boost/preprocessor/arithmetic/sub.hpp boost/preprocessor/array/data.hpp boost/preprocessor/array/elem.hpp boost/preprocessor/array/size.hpp boost/preprocessor/cat.hpp boost/preprocessor/comma_if.hpp boost/preprocessor/config/config.hpp boost/preprocessor/control/detail/dmc/while.hpp boost/preprocessor/control/detail/edg/while.hpp boost/preprocessor/control/detail/msvc/while.hpp boost/preprocessor/control/detail/while.hpp boost/preprocessor/control/expr_iif.hpp boost/preprocessor/control/if.hpp boost/preprocessor/control/iif.hpp boost/preprocessor/control/while.hpp boost/preprocessor/debug/error.hpp boost/preprocessor/detail/auto_rec.hpp boost/preprocessor/detail/check.hpp boost/preprocessor/detail/dmc/auto_rec.hpp boost/preprocessor/detail/is_binary.hpp boost/preprocessor/empty.hpp boost/preprocessor/enum_params.hpp boost/preprocessor/facilities/empty.hpp boost/preprocessor/facilities/identity.hpp boost/preprocessor/identity.hpp boost/preprocessor/inc.hpp boost/preprocessor/iterate.hpp boost/preprocessor/iteration/iterate.hpp boost/preprocessor/list/adt.hpp boost/preprocessor/list/append.hpp boost/preprocessor/list/detail/dmc/fold_left.hpp boost/preprocessor/list/detail/edg/fold_left.hpp boost/preprocessor/list/detail/edg/fold_right.hpp boost/preprocessor/list/detail/fold_left.hpp boost/preprocessor/list/detail/fold_right.hpp boost/preprocessor/list/fold_left.hpp boost/preprocessor/list/fold_right.hpp boost/preprocessor/list/for_each_i.hpp boost/preprocessor/list/reverse.hpp boost/preprocessor/list/transform.hpp boost/preprocessor/logical/and.hpp boost/preprocessor/logical/bitand.hpp boost/preprocessor/logical/bool.hpp boost/preprocessor/logical/compl.hpp boost/preprocessor/punctuation/comma.hpp boost/preprocessor/punctuation/comma_if.hpp boost/preprocessor/repeat.hpp boost/preprocessor/repetition/detail/dmc/for.hpp boost/preprocessor/repetition/detail/edg/for.hpp boost/preprocessor/repetition/detail/for.hpp boost/preprocessor/repetition/detail/msvc/for.hpp boost/preprocessor/repetition/enum_params.hpp boost/preprocessor/repetition/for.hpp boost/preprocessor/repetition/repeat.hpp boost/preprocessor/slot/detail/def.hpp boost/preprocessor/slot/slot.hpp boost/preprocessor/tuple/eat.hpp boost/preprocessor/tuple/elem.hpp boost/preprocessor/tuple/rem.hpp boost/preprocessor/tuple/to_list.hpp boost/shared_ptr.hpp boost/static_assert.hpp boost/throw_exception.hpp boost/type.hpp boost/type_traits/add_reference.hpp boost/type_traits/alignment_of.hpp boost/type_traits/broken_compiler_spec.hpp boost/type_traits/config.hpp boost/type_traits/detail/bool_trait_def.hpp boost/type_traits/detail/bool_trait_undef.hpp boost/type_traits/detail/cv_traits_impl.hpp boost/type_traits/detail/false_result.hpp boost/type_traits/detail/ice_and.hpp boost/type_traits/detail/ice_eq.hpp boost/type_traits/detail/ice_not.hpp boost/type_traits/detail/ice_or.hpp boost/type_traits/detail/is_function_ptr_helper.hpp boost/type_traits/detail/is_function_ptr_tester.hpp boost/type_traits/detail/is_mem_fun_pointer_impl.hpp boost/type_traits/detail/is_mem_fun_pointer_tester.hpp boost/type_traits/detail/size_t_trait_def.hpp boost/type_traits/detail/size_t_trait_undef.hpp boost/type_traits/detail/template_arity_spec.hpp boost/type_traits/detail/type_trait_def.hpp boost/type_traits/detail/type_trait_undef.hpp boost/type_traits/detail/wrap.hpp boost/type_traits/detail/yes_no_type.hpp boost/type_traits/ice.hpp boost/type_traits/integral_constant.hpp boost/type_traits/intrinsics.hpp boost/type_traits/is_abstract.hpp boost/type_traits/is_arithmetic.hpp boost/type_traits/is_array.hpp boost/type_traits/is_class.hpp boost/type_traits/is_const.hpp boost/type_traits/is_convertible.hpp boost/type_traits/is_enum.hpp boost/type_traits/is_float.hpp boost/type_traits/is_function.hpp boost/type_traits/is_integral.hpp boost/type_traits/is_member_function_pointer.hpp boost/type_traits/is_member_pointer.hpp boost/type_traits/is_pod.hpp boost/type_traits/is_pointer.hpp boost/type_traits/is_polymorphic.hpp boost/type_traits/is_reference.hpp boost/type_traits/is_same.hpp boost/type_traits/is_scalar.hpp boost/type_traits/is_union.hpp boost/type_traits/is_void.hpp boost/type_traits/is_volatile.hpp boost/type_traits/msvc/remove_bounds.hpp boost/type_traits/msvc/remove_cv.hpp boost/type_traits/msvc/remove_reference.hpp boost/type_traits/msvc/typeof.hpp boost/type_traits/remove_bounds.hpp boost/type_traits/remove_cv.hpp boost/type_traits/remove_reference.hpp boost/type_traits/type_with_alignment.hpp On Wed, Mar 12, 2008 at 1:57 PM, Amitha Perera <ami...@us...> wrote: > Matt, > > In the interest of getting things rolling *and* you graduating, I think > it'd be okay to have a manual, semi-automatic, or automatic solution. I > think the experience in getting that to work on all the platforms will > tell us a lot about how we can and cannot approach the full generic > solution. I (and perhaps others) can take it from there. > > A clean, default "off" for the feature would make a branch unnecessary. > Moreover, I think a branch in this case will be counter-productive, > because we won't be able to use the dashboard to test all the different > OS/compiler combinations. > > If you could also document failures, and outline your thoughts on how it > should or could be done generically, that'll help when I pick up from > where you leave off. > > Amitha. > |