Code Examples
  Home arrow Code Examples arrow Page 9 - Style Case Studies: Construction Unions
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
ASP Web Hosting  
ASP.NET Web Hosting 
Mobile Linux 
App Generation ROI 
Windows Web Hosting
 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
CODE EXAMPLES

Style Case Studies: Construction Unions
By: Addison-Wesley/Prentice Hall PTR
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 8
    2004-11-16

    Table of Contents:
  • Style Case Studies: Construction Unions
  • Solution
  • Dissecting Construction Unions
  • Into the Code
  • Comments
  • Adding New Types
  • Underhanded Names
  • Toward a Better Way: boost::any
  • Alexandrescu’s Discriminated Unions

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Style Case Studies: Construction Unions - Alexandrescu’s Discriminated Unions


    (Page 9 of 9 )

    Is it possible to fully achieve both of the original goals—safety and avoiding dynamic memory—in a conforming standard C++ implementation? That sounds like a problem that someone like Andrei Alexandrescu would love to sink his teeth into, especially if it could somehow involve complicated templates. As evidenced in [Alexandrescu02], where he describes his discriminated unions (aka Variant) approach, it turns out that:

    • it is (something he would love to tackle), and
    • it can (involve weird templates, and just one quote from [Alexandrescu02] says it all: “Did you know that unions can be templates?”), so he does.

    In short, by performing heroic efforts to push the boundaries of the language as far as possible, Alexandrescu’s Variant comes very close to being a truly portable solution. It falls only slightly short and is probably portable enough in practice even though it too goes beyond the pale of what the Standard guarantees. Its main problem is that, even ignoring alignment-related issues, the Variant code is so complex and advanced that it actually works on very few compilers—in my testing, I only managed to get it to work with one.

    A key part of Alexandrescu’s Variant approach is an attempt to generalize the max_align idea to make it a reusable library facility that can itself still be written in conforming standard C++. The reason for wanting this is specifically to deal with the alignment problems in the code we’ve been analyzing so that a non-dynamic char buffer can continue to be used in relative safety. Alexandrescu makes heroic efforts to use template metaprogramming to calculate a safe alignment. Will it work portably? His discussion of this question follows:

    Even with the best Align, the implementation above is still not 100-percent portable for all types. In theory, someone could implement a compiler that respects the Standard but still does not work properly with discriminated unions. This is because the Standard does not guarantee that all user-defined types ultimately have the alignment of some POD type. Such a compiler, however, would be more of a figment of a wicked language lawyer’s imagination, rather than a realistic language implementation.

    […] Computing alignment portably is hard, but feasible. It never is 100-percent portable.  — [Alexandrescu02]

    There are other key features in Alexandrescu’s approach, notably a union template that takes a typelist template of the types to be contained, visitation support for extensibility, and an implementation technique that will “fake a vtable” for efficiency to avoid an extra indirection when accessing a contained type. These parts are more heavyweight than boost::any but are portable in theory. That “portable in theory” part is important—as with Andrei’s great work in Modern C++ Design [Alexandrescu01], the implementation is so heavy on templates that the code itself contains comments like, “Guaranteed to issue an internal compiler error on: [various popular compilers, Metrowerks, Microsoft, Gnu gcc],” and the mainline test harness contains a commented-out test helpfully labeled “The construct below didn’t work on any compiler.”

    That is Variant’s major weakness: Most real-world compilers don’t even come close to being able to handle this implementation, and the code should be viewed as important but still experimental. I attempted to build Alexandrescu’s Variant code using a variety of compilers: Borland 5.5; Comeau 4.3.0.1; EDG 3.0.1; gcc 2.95, 3.1.1, and 3.2; Intel 7.0; Metrowerks 8.2; and Microsoft VC++ 6.0, 7.0 (2002), and 7.1 (2003). As some readers will know, some of the products in that list are very strong and standards-conforming compilers. None of these compilers could successfully compile Alexandrescu’s template-heavy source as it was provided.

    I tried to massage the code by hand to get it through any of the compilers but was successful only with Microsoft VC++ 7.1 (2003). Most of the compilers didn’t stand a chance, because they did not have nearly strong enough template support to deal with Alexandrescu’s code. (Some emitted a truly prodigious quantity of warnings and errors—Intel 7.0’s response to compiling main.cpp was to spew back an impressive 430K worth—really, nearly half a megabyte—of diagnostic messages.)

    I had to make three changes to get the code to compile without errors (although still with some narrowing-conversion warnings at the highest warning level) under Microsoft VC++ 7.1 (2003):

    • Added a missing typename in class AlignedPOD.

    • Added a missing this-> to make a name dependent in ConverterTo<>::Unit<>::DoVisit().

    • Added a final newline character at the end of several headers, as required by the C++ standard (some conforming compilers aren’t strict about this and allow the absence of a final newline as a conforming extension; VC++ is stricter and requires the newline).

    As the author of [Manley02] commented further about tradeoffs in Alexandrescu’s design:

    It doesn’t use dynamic memory, and it avoids alignment issues and type switching. Unfortunately I don’t have access to a compiler that can compile the code, so I can’t evaluate its performance vs. myunion and any. Alexandrescu’s approach requires 9 supporting header files totaling ~80KB, which introduces its own set of maintenance problems.  — K. Manley, private communication
    Those points are all valid.

    I won’t try to summarize Andrei’s three articles further here, but I encourage readers who are interested in this problem to look them up. They’re available online as indicated in the bibliography.
     
    Guideline: If you want to represent variant types, for now prefer to use boost::any (or something equally simple).

    Once the compiler you are using catches up (in template support) and the Standard catches up (in true alignment support) and Variant libraries catch up (in mature implementations), it will be time to consider using Variant-like library tools as type-safe replacements for unions.

    Summary

    Even if the design and implementation of MYUNION are lacking, the motivating problem is both real and worth considering. I’d like to thank Mr. Manley for taking the time to write his article and raise awareness of the need for variant type support and Kevlin Henney and Andrei Alexandrescu for contributing their own solutions to this area. It is a hard enough problem that Manley’s and Alexandrescu’s approaches are not strictly portable, standards-conforming C++, although Alexandrescu’s Variant makes heroic efforts to get there—Alexandrescu’s design is very close to portable in theory, although the implementation is still far from portable in practice because very few compilers can handle the advanced template code it uses.

    For now, an approach like boost::any is the preferred way to go. If in certain places your measurements tell you that you really need the efficiency or extra features provided by something like Alexandrescu’s Variant, and you have time on your hands and some template know-how, you might experiment with writing your own scaled-back version of the full-blown Variant by applying only the ideas in [Alexandrescu02] that are applicable to your situation.

    This chapter is from Exceptional C++ Style, by Herb Sutter (ISBN 0201760428, copyright 2005. All rights reserved. It is reprinted with permission from Addison-Wesley Professional). Check it out at your favorite bookstore today.

    Buy this book now.


    DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

     

    CODE EXAMPLES ARTICLES

    - Handling Animations and Bitmaps Using GDI+ f...
    - Download a Web Page using the WebClient
    - Creating a Chart using Data from a Database ...
    - The Basics of Charting with the MS Chart Con...
    - Searching Body Text with textRange: Enter th...
    - Searching Body Text with textRange: Building...
    - Searching Body Text with textRange, part 1: ...
    - First Steps in Programming
    - Programming in C
    - Quick Introduction to ASF,ASX, and Networkin...
    - SatView: Pointer Perfect, Part 2: Constructi...
    - SatView: Pointer Perfect, Part 1
    - Style Case Studies: Construction Unions
    - Creating an Engine for Games for Windows
    - Style Case Studies: Generic Callbacks





    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 3 hosted by Hostway
    Stay green...Green IT