www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5097] New: Safer unions with tagged

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5097

           Summary: Safer unions with  tagged
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: bearophile_hugs eml.cc


--- Comment #0 from bearophile_hugs eml.cc 2010-10-21 18:34:53 PDT ---
D language is designed to be safer than C and C++, yet it's not Java, it has to
offer less safe features too, like unions.

The failure of the Cyclone language shows that the safety features need to be
light, minimal, not syntactically intrusive.

The simpler way to make unions safe is to introduce an attribute as  tagged.

When an union has a  tagged attribute, one word is added by the compiler to the
union, that makes sure (with runtime tests) that the last written field is
read. In release mode this invisible field and their tests vanish (a better
feature is to test and enforce this at compile time, but this requires a more
complex type system that D doesn't have).

(If you want even more safety, unions with the  tagged attribute may not allow
to take the address of fields, to avoid bypassing the runtime cheeks.)

In the end the programmer that wants to use safer unions in D may just add the
 tagged attribute, nothing else is required, and the union semantics is
unchanged (just its size is changed in non-release mode). So this is a very
light and easy to use safety net:


 tagged union Foo {
    int i;
    float f;
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 21 2010
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5097



--- Comment #1 from bearophile_hugs eml.cc 2010-10-21 18:40:42 PDT ---
This is not the same as std.variant.Algebraic because:
- There is no way for the programmer to read the tag, because the tag and its
tests vanish in release mode.
- Unions may have methods, they are quite more flexible than Algebraic.
- If you translate C code to D you may not want to modify too much the code, so
you will not use Algebraic. But you may add the  tagged attribute to unions
translated from C. The size of the union changes, but hopefully this doesn't
cause disasters often (if changing the size of the union is seen as not
acceptable, then the union tags may be stored elsewhere on the heap and stack,
but this may increase the implementation complexity of this feature).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 21 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5097


Andrei Alexandrescu <andrei metalanguage.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |andrei metalanguage.com
         Resolution|                            |INVALID


--- Comment #2 from Andrei Alexandrescu <andrei metalanguage.com> 2010-10-21
20:00:28 PDT ---
(In reply to comment #1)
 This is not the same as std.variant.Algebraic because:
 - There is no way for the programmer to read the tag, because the tag and its
 tests vanish in release mode.
This does not justify a new language feature. Anyone could define a private tag that doesn't vanish in release mode.
 - Unions may have methods, they are quite more flexible than Algebraic.
A struct with an Algebraic member can define methods.
 - If you translate C code to D you may not want to modify too much the code, so
 you will not use Algebraic. But you may add the  tagged attribute to unions
 translated from C. The size of the union changes, but hopefully this doesn't
 cause disasters often (if changing the size of the union is seen as not
 acceptable, then the union tags may be stored elsewhere on the heap and stack,
 but this may increase the implementation complexity of this feature).
Translation from C is hardly improved as use of union is rather rare. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 21 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5097



--- Comment #3 from Andrei Alexandrescu <andrei metalanguage.com> 2010-10-21
20:27:47 PDT ---
(In reply to comment #2)
 (In reply to comment #1)
 This is not the same as std.variant.Algebraic because:
 - There is no way for the programmer to read the tag, because the tag and its
 tests vanish in release mode.
This does not justify a new language feature. Anyone could define a private tag that doesn't vanish in release mode.
Oops, I meant "does". Andrei -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 21 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5097



--- Comment #4 from bearophile_hugs eml.cc 2010-10-22 04:43:19 PDT ---
(In reply to comment #2)

Thank you for your comments.

 Anyone could define a private tag that doesn't vanish in release mode.
In a union with tagged the attributes become properties (functions) and they contain a test over the private tag, to make sure you read the last written field. You may of course write such proprieties by yourself, but the point of this feature is to catch possible bugs, and those handwritten properties code may contain bugs.
 - Unions may have methods, they are quite more flexible than Algebraic.
A struct with an Algebraic member can define methods.
But this requires you to change the code that uses the union/struct. While the tagged is a clean change that's almost transparent.
 Translation from C is hardly improved as use of union is rather rare.
Usage of low-level features (and simpler porting of existing C code) is what may give interest in using D instead of for example Java. This gives 120_000 usages for the word "union" in C: http://www.google.com/codesearch?as_q=union&btnG=Search+Code&hl=en&as_package=&as_lang=c&as_filename=&as_class=&as_function=&as_license=&as_case= And 49_000 in C++: http://www.google.com/codesearch?as_q=union&btnG=Search+Code&hl=en&as_package=&as_lang=c%2B%2B&as_filename=&as_class=&as_function=&as_license=&as_case= Lower level features too of D may enjoy to become safer, where possible. I have proposed many other little features that improve the safety of low level D features. You can't always use high level features in D, and ignoring those sources of bugs is not good. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Oct 22 2010
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5097


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |clugdbug yahoo.com.au


--- Comment #5 from Don <clugdbug yahoo.com.au> 2010-10-22 05:55:54 PDT ---
Sorry bearophile, this looks to me like a feature that doesn't make much sense. 

(1) I don't think there are many potential bugs it could catch
It would be foolish to port C code which hasn't been fully debugged. (If it
hasn't been debugged, you should be rewriting it in D anyway). So it's not
going to find bugs in existing code, only in new code.
And unions are nasty beasts, that should be well encapsulated, so there should
be very little code that uses them.

(2)It would hardly ever be usable.
Most uses of unions in C would probably not work with this feature. In just
about every union I've ever written, the alignment and size were crucial.
In just about every case that it wasn't, a variant would have been usable.
So...

(3) Most of the cases where it would be usable and could catch bugs, are
covered with std.variant.Algebraic already.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 22 2010
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5097



--- Comment #6 from bearophile_hugs eml.cc 2010-10-22 10:35:20 PDT ---
Thank you Don and Andrei for all the answers, you are right.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 22 2010