Thread: Typesafe, generalized aliasing

  1. #1
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937

    Typesafe, generalized aliasing

    Hello,

    Is there a way to locally rename members of a class? I'm looking for a way to have std::pair<t1,t2>::first be synonymous with std::pair<t1,t2>::type_specific. I'd prefer not to create my own type.

    Thanks
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  2. #2
    Banned
    Join Date
    Dec 2008
    Location
    Maputo, Mozambique
    Posts
    82
    {No}

  3. #3
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    <Bummer>
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  4. #4
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    Will the constructor of this result in undefined behavior? (So far, so good)
    Code:
    template<class T1, class T2>
    struct point : public std::pair<T1,T2>
    {
    	point() : std::pair<T1,T2>(), x(this->first), y(this->second) {}
    	T1 & x;
    	T2 & y;
    };
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    (I don't see why it would.)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    [Well,] (are we done with this?)
    I thought that maybe the pair, and thus first and second wouldn't be constructed until the body of point's constructor. But it seems not. Actually, I think the C++ FAQ covers this...
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It's safe. It's also a big waste of space, since your point class is suddenly two words larger. This will probably double or triple its size. No compiler will optimize these references away.

    On the other hand, if you're not afraid of global functions, you can write them thus:
    Code:
    template <typename T1, typename T2>
    T1 x(const std::pair<T1, T2> &pt)
    {
      return pt.first;
    }
    
    template <typename T1, typename T2>
    T2 y(const std::pair<T1, T2> &pt)
    {
      return pt.second;
    }
    
    x(pt);
    y(pt);
    The syntax is admittedly a bit weird, but nothing out of the ordinary for hardcore generic programmers.

    Or you could write accessor functions:
    Code:
    template <typename T1, typename T2>
    struct point : std::pair<T1, T2>
    {
      T1& x() { return this->first; }
      T2& y() { return this->second; }
    };
    
    pt.x() = 100;
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    Hm. That's a good solution. Why wouldn't a clever optimizer remove the references in my code? Certainly it could notice that the references are used only exactly when that to which they refer could be used.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Compilers follow strict rules in the class layouts they generate. If there's a field "x" in the code, there'd better be something equivalent in the binary layout.

    Optimizing these references away requires a data flow analyzer to prove that x and y ever only point to first and second of the same object, respectively. While this is very much within the realm of the possible for the compiler, this flow analyzer is only run when optimizations are turned on - it's very expensive to run. So it would depend on the optimization settings (and perhaps even more esoteric issues) whether the fields are there or not. However, the existence of the fields is a matter of the binary interface.
    Breaking binary interface in codegen between release and debug builds is a big no-no.

    Only codegen, though. Libraries far too often don't give a damn. The GCC guys are good with this - you can intermix debug and release code pretty freely, even with STL types in the mix. However, MS has no such scruples. The MS STL breaks binary interface with every little compiler switch, it sometimes seems.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #10
    Banned
    Join Date
    Dec 2008
    Location
    Maputo, Mozambique
    Posts
    82
    Very interesting. Is there a reason why Microsoft does it this way?

  11. #11
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No official one, no. My theory is that they're too lazy to do it properly.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  12. #12
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    After reading the Wikipedia article, I have this question:
    What is a general reason for not wanting to change the binary interface between build profiles?
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Suppose you have a number of projects. One of those is a library of basic utility classes. The second is a DLL used in several projects, which uses these utilities in its interface. The third is an executable.

    If the binary interface changes between release and debug, then the executable, the DLL, and the basic utilities must always match in their build profile. Always.

    OK, this isn't too much of a burden if the projects are all yours.

    However, what if they aren't? Suppose the basic utility is the C++ standard library. Microsoft's SL changes binary interface not only between release and debug, but also between _SCL_SECURE=1 and 0. Suppose the DLL is not by you, but by a third party. You only get a release version, and you don't get the source. The DLL uses standard library components in its interface.
    Then this means:
    1) You cannot build debug variants of your program.
    2) Your _SCL_SECURE setting must match that of the DLL. Oh, did I mention that this setting can slow down STL-intensive applications by a factor of 10?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by CornedBee View Post
    No official one, no. My theory is that they're too lazy to do it properly.
    I think it's because they're caught between a rock and a hard place.
    They absolutely must have all that iterator checking stuff in there in debug buillds, which definitely involves extra fields, but they also must have the fastest possible release build implementation so that people will use their compiler for the nice fast code it generates.
    So therefore you lose binary compatibility.
    It's like that rule that you can have cheap, fast, or secure, but not all three.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    They don't have a very fast release version by default - they erred on the side of safety, I think. But that's not the point.

    The point is that they handled things in a very poor fashion. GCC's standard library is built so that in the rare cases where do mix up incompatible versions, you get linker errors. MS's version is built so that the program crashes. Oops, there goes the safety.
    Also, in GCC's version the debug and the release version can and do coexist in a single runtime image (executable plus libraries). In MS's version this leads to load errors or crashes.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. generalized recursive for loop
    By moddinati in forum C Programming
    Replies: 3
    Last Post: 12-18-2008, 04:58 PM
  2. ideas for a generalized unit-handling class
    By m37h0d in forum C++ Programming
    Replies: 10
    Last Post: 06-19-2008, 09:42 AM
  3. What's a good generalized data structures book?
    By indigo0086 in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 11-16-2006, 01:01 PM
  4. Anti aliasing
    By arjunajay in forum Windows Programming
    Replies: 7
    Last Post: 08-15-2006, 08:24 PM
  5. typesafe callback system
    By gandalf_bar in forum C++ Programming
    Replies: 1
    Last Post: 05-22-2004, 06:35 AM