Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #70942 > unrolled thread

Union type punning in C++

Started byMr Flibble <flibbleREMOVETHISBIT@i42.co.uk>
First post2020-01-01 19:24 +0000
Last post2020-01-13 16:29 -0800
Articles 20 on this page of 135 — 18 participants

Back to article view | Back to comp.lang.c++


Contents

  Union type punning in C++ Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2020-01-01 19:24 +0000
    Re: Union type punning in C++ boltar@nowhere.org - 2020-01-02 09:36 +0000
    Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-02 03:34 -0800
      Re: Union type punning in C++ Bo Persson <bo@bo-persson.se> - 2020-01-02 12:49 +0100
        Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-02 04:52 -0800
          Re: Union type punning in C++ boltar@nowhere.org - 2020-01-02 17:22 +0000
            Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-02 10:26 -0800
              Re: Union type punning in C++ Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2020-01-02 21:54 +0000
                Re: Union type punning in C++ boltar@nowhere.org - 2020-01-03 14:49 +0000
                  Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-03 17:11 +0100
                  Re: Union type punning in C++ Chris Vine <chris@cvine--nospam--.freeserve.co.uk> - 2020-01-03 17:55 +0000
              Re: Union type punning in C++ boltar@nowhere.org - 2020-01-03 09:55 +0000
                Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-03 11:20 +0100
                Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-03 02:21 -0800
                  Re: Union type punning in C++ boltar@nowhere.org - 2020-01-03 14:55 +0000
                    Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-03 16:04 +0100
                      Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-03 14:45 -0800
                        Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 01:26 +0100
                          Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-03 16:55 -0800
                            Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 01:02 +0000
                              Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-03 17:06 -0800
                    Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-03 07:34 -0800
                      Re: Union type punning in C++ boltar@nowhere.org - 2020-01-03 16:12 +0000
                        Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-03 08:49 -0800
                        Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-03 19:28 +0100
                          Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-03 18:54 +0000
                            Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 01:25 +0100
                              Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 00:28 +0000
                                Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 01:41 +0100
                                  Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 00:52 +0000
                                    Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 08:08 +0100
                                      Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 08:34 +0100
                                        Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 08:43 +0100
                                        Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 08:20 +0000
                                          Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 09:25 +0100
                                      Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 08:25 +0000
                                        Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 09:25 +0100
                                          Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 08:27 +0000
                                            Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 09:36 +0100
                                              Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 08:41 +0000
                                                Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 09:49 +0100
                                                  Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 09:01 +0000
                                                    Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 10:02 +0100
                                                      Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 09:19 +0000
                                                        Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 10:38 +0100
                              Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-04 12:45 +0100
                                Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 12:00 +0000
                                  Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 13:03 +0100
                                Re: Union type punning in C++ Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 14:22 +0100
                        Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-03 14:46 -0800
                      Re: Union type punning in C++ Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-01-03 10:32 -0800
                        Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-03 10:43 -0800
                          Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-03 18:55 +0000
              Re: Union type punning in C++ Daniel <danielaparker@gmail.com> - 2020-01-08 09:40 -0800
                Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-08 13:23 -0800
                  Re: Union type punning in C++ Daniel <danielaparker@gmail.com> - 2020-01-08 22:41 -0800
                  Re: Union type punning in C++ Daniel <danielaparker@gmail.com> - 2020-01-08 22:52 -0800
                    Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-09 12:59 -0800
                      Re: Union type punning in C++ Daniel <danielaparker@gmail.com> - 2020-01-09 13:32 -0800
                      Re: Union type punning in C++ Mister2U@honorific.org - 2020-01-10 12:28 +0000
                        Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-10 14:02 +0100
                          Re: Union type punning in C++ Mister2U@honorific.org - 2020-01-10 16:21 +0000
                            Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-10 19:18 +0100
                              Re: Union type punning in C++ Daniel <danielaparker@gmail.com> - 2020-01-10 15:41 -0800
                                Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-11 12:01 +0100
                                  Re: Union type punning in C++ Daniel <danielaparker@gmail.com> - 2020-01-11 07:05 -0800
                                    Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-11 23:53 +0100
                                      Re: Union type punning in C++ Mr Flibble <flibble@i42.removethisbit.co.uk> - 2020-01-12 01:41 +0000
                                        Re: Union type punning in C++ Daniel <danielaparker@gmail.com> - 2020-01-11 19:00 -0800
                                          Re: Union type punning in C++ Mr Flibble <flibble@i42.removethisbit.co.uk> - 2020-01-13 17:32 +0000
                              Re: Union type punning in C++ Mister2U@honorific.org - 2020-01-11 11:53 +0000
                                Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-11 13:20 +0100
                                  Re: Union type punning in C++ Mister2U@honorific.org - 2020-01-11 12:33 +0000
                                    Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-11 14:28 +0100
                            Re: Union type punning in C++ Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-11 10:48 +0000
                        Re: Union type punning in C++ Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-11 11:05 +0000
                          Re: Union type punning in C++ Mister2U@honorific.org - 2020-01-11 11:55 +0000
            Re: Union type punning in C++ Bo Persson <bo@bo-persson.se> - 2020-01-02 21:12 +0100
              Re: Union type punning in C++ boltar@nowhere.org - 2020-01-03 14:46 +0000
                Re: Union type punning in C++ Bo Persson <bo@bo-persson.se> - 2020-01-03 20:01 +0100
            Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-02 23:23 +0100
    Re: Union type punning in C++ peter koch <peter.koch.larsen@gmail.com> - 2020-01-02 12:39 -0800
    Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-02 15:39 -0800
      Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-02 16:58 -0800
        Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-02 17:55 -0800
          Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-03 00:40 -0800
            Re: Union type punning in C++ Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2020-01-03 14:04 +0000
              Re: Union type punning in C++ David Brown <david.brown@hesbynett.no> - 2020-01-03 15:24 +0100
                Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-03 14:34 -0800
                  Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-03 22:59 +0000
                    Re: Union type punning in C++ Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2020-01-04 00:11 +0000
                      Re: Union type punning in C++ Melzzzzz <Melzzzzz@zzzzz.com> - 2020-01-04 00:21 +0000
                        Re: Union type punning in C++ Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2020-01-04 00:26 +0000
                          Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-04 16:51 -0800
                      Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-03 18:47 -0800
                        Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-03 19:07 -0800
              Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-03 06:47 -0800
                Re: Union type punning in C++ Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2020-01-03 14:57 +0000
                  Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-03 07:38 -0800
                    Re: Union type punning in C++ Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2020-01-03 17:06 +0000
                      Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-03 11:05 -0800
            Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-03 14:38 -0800
              Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-03 22:37 -0800
        Re: Union type punning in C++ Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-11 07:10 -0800
          Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-11 10:23 -0800
            Re: Union type punning in C++ Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-13 09:01 -0800
              Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-13 11:03 -0800
                Re: Union type punning in C++ James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-13 12:48 -0800
                  Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-13 14:15 -0800
                    Re: Union type punning in C++ James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-13 21:47 -0500
                      Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-13 23:44 -0800
                        Re: Union type punning in C++ James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-14 08:26 -0500
                Re: Union type punning in C++ Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-14 07:30 -0800
                  Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-14 09:11 -0800
                    Re: Union type punning in C++ James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-14 21:52 -0500
                      Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-14 23:15 -0800
                    Re: Union type punning in C++ Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-21 02:03 -0800
      Re: Union type punning in C++ Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-11 07:28 -0800
        Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-11 20:40 -0800
          Re: Union type punning in C++ James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-12 20:16 -0500
            Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-12 17:28 -0800
              Re: Union type punning in C++ James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-12 21:53 -0500
                Re: Union type punning in C++ Manfred <noname@add.invalid> - 2020-01-13 18:50 +0100
                Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-13 16:21 -0800
              Re: Union type punning in C++ Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-13 08:57 -0800
                Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-13 16:27 -0800
                  Re: Union type punning in C++ Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-14 07:05 -0800
                    Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-14 20:58 -0800
                      Re: Union type punning in C++ Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-21 03:47 -0800
              Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-15 01:22 -0800
                Re: Union type punning in C++ James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-15 08:04 -0500
                  Re: Union type punning in C++ Öö Tiib <ootiib@hot.ee> - 2020-01-15 09:38 -0800
                    Re: Union type punning in C++ James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-15 11:01 -0800
          Re: Union type punning in C++ Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-13 08:37 -0800
            Re: Union type punning in C++ "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-01-13 16:29 -0800

Page 6 of 7 — ← Prev page 1 2 3 4 5 [6] 7  Next page →


#71046

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-03 11:05 -0800
Message-ID<a2a454b2-df15-4ee3-a441-0acc63d2eaad@googlegroups.com>
In reply to#71037
On Friday, 3 January 2020 19:06:30 UTC+2, Mr Flibble  wrote:
> On 03/01/2020 15:38, Öö Tiib wrote:
> > On Friday, 3 January 2020 16:57:50 UTC+2, Mr Flibble  wrote:
> >> On 03/01/2020 14:47, Öö Tiib wrote:
> >>> On Friday, 3 January 2020 16:04:31 UTC+2, Mr Flibble  wrote:
> >>>> On 03/01/2020 08:40, Öö Tiib wrote:
> >>>>> On Friday, 3 January 2020 03:56:03 UTC+2, Chris M. Thomasson  wrote:
> >>>>>> On 1/2/2020 4:58 PM, Öö Tiib wrote:
> >>>>>>> On Friday, 3 January 2020 01:39:54 UTC+2, Chris M. Thomasson  wrote:
> >>>>>>>> On 1/1/2020 11:24 AM, Mr Flibble wrote:
> >>>>>>>>> Undefined behaviour aside is C++ union type punning an acceptable hack
> >>>>>>>>> or not, given that it is legal in C?
> >>>>>>>>> If it works on all the compilers I care about does it really matter that
> >>>>>>>>> it is *currently* classed as undefined behaviour?
> >>>>>>>>> I would say that everyone has "secretly" fucking done it some time or
> >>>>>>>>> other so the C++ Standards Committee should get there act together and
> >>>>>>>>> legalize it like it has been in C.
> >>>>>>>>> Can anyone provide a straight answer to this?
> >>>>>>>>
> >>>>>>>> Is there some cryptic hidden thing in the standard that just might
> >>>>>>>> "allow" for the following code to run without ub?
> >>>>>>>
> >>>>>>> Possibly.
> >>>>>> [...]
> >>>>>>> By my understanding it can easily be that it is not undefined behavior
> >>>>>>> there at all. What is the motivation of writing code like that?
> >>>>>>
> >>>>>> Mainly to boil things down for the example. Also, one can use the base
> >>>>>> object as a, say, sequence counter. The types in the union can be used
> >>>>>> for, an event dispatch.
> >>>>>
> >>>>> Hmm. I'm not sure I understand the example problem. What the counter
> >>>>> counts and  why you do not keep it outside of union?
> >>>>>
> >>>>>> Say the union object is being represented as an object_1.
> >>>>>>
> >>>>>> object_1* o1 = &o.o1;
> >>>>>>
> >>>>>> o1->b.p0 += 1;
> >>>>>> o1->p0 += 1;
> >>>>>> o1->p1 += 3;
> >>>>>
> >>>>> Above looks ill-formed, diagnostic required.
> >>>>> The p0 and p1 were of class types without operator+=(int) specified.
> >>>>>
> >>>>>> o1->b.p0 += 1;
> >>>>>>
> >>>>>> Now, we can read the sequence count base now matter if we are working
> >>>>>> with an object_0 or object_1.
> >>>>>>
> >>>>>> int seq = o.b.p0;
> >>>>>
> >>>>> I'm still confused. This is all about some kind of aliases and references
> >>>>> (that likely work fine). But existence of those does simplify nothing for
> >>>>> me. There is apparent desire to have multiple members of union active
> >>>>> at same time. That also does confuse me. For me it is not question if it
> >>>>> is defined behavior but uncertainty about why I need it regardless if it
> >>>>> is defined behavior or not.
> >>>>
> >>>> I need this ability so I can have a swizzle class.
> >>>
> >>> Ok. Then you need to make your swizzle class "standard layout class"
> >>> ([class] 7) with all of non-static data members being "common initial
> >>> sequence".
> >>>
> >>> class.mem] 23
> >>> "In a standard-layout union with an active member (12.3) of struct
> >>> type T1, it is permitted to read a non-static data member m of
> >>> another union member of struct type T2 provided m is part of the
> >>> common initial sequence of T1 and T2; the behavior is as if the
> >>> corresponding member of T1 were nominated."
> >>>
> >>> And from [class.union] I have strong impression that writing into
> >>> such union member just ends lifetime of previous active member
> >>> and starts lifetime of written into active member without any
> >>> cleanup or initializations done.
> >>
> >> No that won't help me with my swizzle class.
> > 
> > Why? Can it be rewritten in a way that will help with it or are
> > there some fundamental problems?
> 
> You can find my swizzle base class here:
> 
> https://github.com/i42output/neoGFX/blob/master/include/neogfx/core/swizzle_array.hpp

Here is union containing swizzles but there are also

                array_type v; 

It has common initial sequence since has same as swizzle::array_type.

                struct // todo: alignment, padding?
                {
                    value_type x;
                    value_type y;
                    value_type z;
                };

Get rid of it, or replace with your swizzles.

> used by my swizzle class here:
> 
> https://github.com/i42output/neoGFX/blob/master/include/neogfx/core/swizzle.hpp

Hmm. Lets see:

|  A class S is a standard-layout class if it: 
| —(7.1) has no non-static data members of type non-standard-layout class (or array of such types) or reference,

Check. Unless your swizzle::array_type is non-standard-layout class.

| —(7.2) has no virtual functions (13.3) and no virtual base classes (13.1),
 
Check.

| —(7.3) has the same access control (Clause 14) for all non-static data members, 

Check. Public.

| —(7.4) has no non-standard-layout base classes, 
| —(7.5) has at most one base class subobject of any given type,
| —(7.6) has all non-static data members and bit-fields in the class and its base classes first declared in the same class, and 
| —(7.7) has no element of the set M(S) of types (defined below) as a base class.108 M(X) is defined as follows: etc.

Check. No base classes.

> used by my vector class here:
> 
> https://github.com/i42output/neoGFX/blob/master/include/neogfx/core/numerical.hpp

[toc] | [prev] | [next] | [standalone]


#71053

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2020-01-03 14:38 -0800
Message-ID<quofo5$cf5$2@gioia.aioe.org>
In reply to#71005
On 1/3/2020 12:40 AM, Öö Tiib wrote:
> On Friday, 3 January 2020 03:56:03 UTC+2, Chris M. Thomasson  wrote:
>> On 1/2/2020 4:58 PM, Öö Tiib wrote:
>>> On Friday, 3 January 2020 01:39:54 UTC+2, Chris M. Thomasson  wrote:
>>>> On 1/1/2020 11:24 AM, Mr Flibble wrote:
>>>>> Undefined behaviour aside is C++ union type punning an acceptable hack
>>>>> or not, given that it is legal in C?
>>>>> If it works on all the compilers I care about does it really matter that
>>>>> it is *currently* classed as undefined behaviour?
>>>>> I would say that everyone has "secretly" fucking done it some time or
>>>>> other so the C++ Standards Committee should get there act together and
>>>>> legalize it like it has been in C.
>>>>> Can anyone provide a straight answer to this?
>>>>
>>>> Is there some cryptic hidden thing in the standard that just might
>>>> "allow" for the following code to run without ub?
>>>
>>> Possibly.
>> [...]
>>> By my understanding it can easily be that it is not undefined behavior
>>> there at all. What is the motivation of writing code like that?
>>
>> Mainly to boil things down for the example. Also, one can use the base
>> object as a, say, sequence counter. The types in the union can be used
>> for, an event dispatch.
> 
> Hmm. I'm not sure I understand the example problem. What the counter
> counts and  why you do not keep it outside of union?
> 
>> Say the union object is being represented as an object_1.
>>
>> object_1* o1 = &o.o1;
>>
>> o1->b.p0 += 1;
>> o1->p0 += 1;
>> o1->p1 += 3;
> 
> Above looks ill-formed, diagnostic required.
> The p0 and p1 were of class types without operator+=(int) specified.

These are using the same POD structs in my original example:
____________________________
struct base
{
     int p0;
};

struct object_0
{
     base b;
     int p0;
};

struct object_1
{
     base b;
     int p0;
     int p1;
};

union object
{
     base b;
     object_0 o0;
     object_1 o1;
};
____________________________

Everything boils down to int types, so no special operators need to be 
defined.


> 
>> o1->b.p0 += 1;
>>
>> Now, we can read the sequence count base now matter if we are working
>> with an object_0 or object_1.
>>
>> int seq = o.b.p0;
> 
> I'm still confused. This is all about some kind of aliases and references
> (that likely work fine). But existence of those does simplify nothing for
> me. There is apparent desire to have multiple members of union active
> at same time. That also does confuse me. For me it is not question if it
> is defined behavior but uncertainty about why I need it regardless if it
> is defined behavior or not.
> 

[toc] | [prev] | [next] | [standalone]


#71082

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-03 22:37 -0800
Message-ID<27b17cb5-7a68-43e0-ae6b-ef4ca31cf8ba@googlegroups.com>
In reply to#71053
On Saturday, 4 January 2020 00:38:08 UTC+2, Chris M. Thomasson  wrote:
> On 1/3/2020 12:40 AM, Öö Tiib wrote:
> > On Friday, 3 January 2020 03:56:03 UTC+2, Chris M. Thomasson  wrote:
> >> On 1/2/2020 4:58 PM, Öö Tiib wrote:
> >>> On Friday, 3 January 2020 01:39:54 UTC+2, Chris M. Thomasson  wrote:
> >>>> On 1/1/2020 11:24 AM, Mr Flibble wrote:
> >>>>> Undefined behaviour aside is C++ union type punning an acceptable hack
> >>>>> or not, given that it is legal in C?
> >>>>> If it works on all the compilers I care about does it really matter that
> >>>>> it is *currently* classed as undefined behaviour?
> >>>>> I would say that everyone has "secretly" fucking done it some time or
> >>>>> other so the C++ Standards Committee should get there act together and
> >>>>> legalize it like it has been in C.
> >>>>> Can anyone provide a straight answer to this?
> >>>>
> >>>> Is there some cryptic hidden thing in the standard that just might
> >>>> "allow" for the following code to run without ub?
> >>>
> >>> Possibly.
> >> [...]
> >>> By my understanding it can easily be that it is not undefined behavior
> >>> there at all. What is the motivation of writing code like that?
> >>
> >> Mainly to boil things down for the example. Also, one can use the base
> >> object as a, say, sequence counter. The types in the union can be used
> >> for, an event dispatch.
> > 
> > Hmm. I'm not sure I understand the example problem. What the counter
> > counts and  why you do not keep it outside of union?
> > 
> >> Say the union object is being represented as an object_1.
> >>
> >> object_1* o1 = &o.o1;
> >>
> >> o1->b.p0 += 1;
> >> o1->p0 += 1;
> >> o1->p1 += 3;
> > 
> > Above looks ill-formed, diagnostic required.
> > The p0 and p1 were of class types without operator+=(int) specified.
> 
> These are using the same POD structs in my original example:
> ____________________________
> struct base
> {
>      int p0;
> };
> 
> struct object_0
> {
>      base b;
>      int p0;
> };
> 
> struct object_1
> {
>      base b;
>      int p0;
>      int p1;
> };
> 
> union object
> {
>      base b;
>      object_0 o0;
>      object_1 o1;
> };
> ____________________________
> 
> Everything boils down to int types, so no special operators need to be 
> defined.

Sorry, you are correct, I misread or misremembered. The problem it
supposedly solves is bit confusing for me. I am not saying we do
not need it just that I do not understand in what situation I
need it.

> 
> 
> > 
> >> o1->b.p0 += 1;
> >>
> >> Now, we can read the sequence count base now matter if we are working
> >> with an object_0 or object_1.
> >>
> >> int seq = o.b.p0;
> > 
> > I'm still confused. This is all about some kind of aliases and references
> > (that likely work fine). But existence of those does simplify nothing for
> > me. There is apparent desire to have multiple members of union active
> > at same time. That also does confuse me. For me it is not question if it
> > is defined behavior but uncertainty about why I need it regardless if it
> > is defined behavior or not.
> >

[toc] | [prev] | [next] | [standalone]


#71290

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-01-11 07:10 -0800
Message-ID<86d0bq2fmi.fsf@linuxsc.com>
In reply to#70988
Tiib writes:

> On Friday, 3 January 2020 01:39:54 UTC+2, Chris M. Thomasson  wrote:
>
>> On 1/1/2020 11:24 AM, Mr Flibble wrote:
>>
>>> Undefined behaviour aside is C++ union type punning an acceptable hack
>>> or not, given that it is legal in C?
>>> If it works on all the compilers I care about does it really matter that
>>> it is *currently* classed as undefined behaviour?
>>> I would say that everyone has "secretly" fucking done it some time or
>>> other so the C++ Standards Committee should get there act together and
>>> legalize it like it has been in C.
>>> Can anyone provide a straight answer to this?
>>
>> Is there some cryptic hidden thing in the standard that just might
>> "allow" for the following code to run without ub?
>
> Possibly.
>
>> ___________________________
>> #include <iostream>
>>
>> struct base
>> {
>>      int p0;
>> };
>
> Standard layout classes have lot of additional guarantees.
>
>> struct object_0
>> {
>>      base b;
>>      int p0;
>> };
>
> Standard layout with common initial sequence with base.

Unless I'm missing something the two struct types base and object_0
don't have a common initial sequence (or we might say the common
initial sequence is the empty set).  The first member of base is of
type int.  The first member of object_0 is of type base.  These two
types, int and base, are not layout-compatible:  they are not the
same type;  they are not layout-compatible enumerations;  and they
are not layout-compatible standard-layout class types.  Hence there
is no common initial sequence.

[toc] | [prev] | [next] | [standalone]


#71292

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-11 10:23 -0800
Message-ID<140b2e3a-cc88-45f9-a292-efd471e3c789@googlegroups.com>
In reply to#71290
On Saturday, 11 January 2020 17:10:43 UTC+2, Tim Rentsch  wrote:
> Tiib writes:
> 
> > On Friday, 3 January 2020 01:39:54 UTC+2, Chris M. Thomasson  wrote:
> >
> >> On 1/1/2020 11:24 AM, Mr Flibble wrote:
> >>
> >>> Undefined behaviour aside is C++ union type punning an acceptable hack
> >>> or not, given that it is legal in C?
> >>> If it works on all the compilers I care about does it really matter that
> >>> it is *currently* classed as undefined behaviour?
> >>> I would say that everyone has "secretly" fucking done it some time or
> >>> other so the C++ Standards Committee should get there act together and
> >>> legalize it like it has been in C.
> >>> Can anyone provide a straight answer to this?
> >>
> >> Is there some cryptic hidden thing in the standard that just might
> >> "allow" for the following code to run without ub?
> >
> > Possibly.
> >
> >> ___________________________
> >> #include <iostream>
> >>
> >> struct base
> >> {
> >>      int p0;
> >> };
> >
> > Standard layout classes have lot of additional guarantees.
> >
> >> struct object_0
> >> {
> >>      base b;
> >>      int p0;
> >> };
> >
> > Standard layout with common initial sequence with base.
> 
> Unless I'm missing something the two struct types base and object_0
> don't have a common initial sequence (or we might say the common
> initial sequence is the empty set).  The first member of base is of
> type int.  The first member of object_0 is of type base.  These two
> types, int and base, are not layout-compatible:  they are not the
> same type;  they are not layout-compatible enumerations;  and they
> are not layout-compatible standard-layout class types.  Hence there
> is no common initial sequence.

Address of standard layout object and its first element is required to
be same so standard layout struct x and other struct that has  x as
first element have the whole x as common initial sequence.

[toc] | [prev] | [next] | [standalone]


#71307

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-01-13 09:01 -0800
Message-ID<86r203guiq.fsf@linuxsc.com>
In reply to#71292
Tiib writes:

> On Saturday, 11 January 2020 17:10:43 UTC+2, Tim Rentsch  wrote:
>
>> Tiib writes:
>>
>>> On Friday, 3 January 2020 01:39:54 UTC+2, Chris M. Thomasson  wrote:
>>>
>>>> On 1/1/2020 11:24 AM, Mr Flibble wrote:
>>>>
>>>>> Undefined behaviour aside is C++ union type punning an acceptable hack
>>>>> or not, given that it is legal in C?
>>>>> If it works on all the compilers I care about does it really matter that
>>>>> it is *currently* classed as undefined behaviour?
>>>>> I would say that everyone has "secretly" fucking done it some time or
>>>>> other so the C++ Standards Committee should get there act together and
>>>>> legalize it like it has been in C.
>>>>> Can anyone provide a straight answer to this?
>>>>
>>>> Is there some cryptic hidden thing in the standard that just might
>>>> "allow" for the following code to run without ub?
>>>
>>> Possibly.
>>>
>>>> ___________________________
>>>> #include <iostream>
>>>>
>>>> struct base
>>>> {
>>>>      int p0;
>>>> };
>>>
>>> Standard layout classes have lot of additional guarantees.
>>>
>>>> struct object_0
>>>> {
>>>>      base b;
>>>>      int p0;
>>>> };
>>>
>>> Standard layout with common initial sequence with base.
>>
>> Unless I'm missing something the two struct types base and object_0
>> don't have a common initial sequence (or we might say the common
>> initial sequence is the empty set).  The first member of base is of
>> type int.  The first member of object_0 is of type base.  These two
>> types, int and base, are not layout-compatible:  they are not the
>> same type;  they are not layout-compatible enumerations;  and they
>> are not layout-compatible standard-layout class types.  Hence there
>> is no common initial sequence.
>
> Address of standard layout object and its first element is required to
> be same so standard layout struct x and other struct that has  x as
> first element have the whole x as common initial sequence.

The first member of struct base is of type 'int'.  The first member of
struct object_0 is of type 'base'.  The two types, 'int' and 'base',
are not layout compatible.  Do you agree or disagree?

If you agree, then because the types of those members are not layout
compatible, those members are not part of a common initial sequence.
Do you agree or disagree?

[toc] | [prev] | [next] | [standalone]


#71311

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-13 11:03 -0800
Message-ID<2e087cbf-8a15-4109-b199-f200487745f6@googlegroups.com>
In reply to#71307
On Monday, 13 January 2020 19:02:00 UTC+2, Tim Rentsch  wrote:
> Tiib writes:
> 
> > On Saturday, 11 January 2020 17:10:43 UTC+2, Tim Rentsch  wrote:
> >
> >> Tiib writes:
> >>
> >>> On Friday, 3 January 2020 01:39:54 UTC+2, Chris M. Thomasson  wrote:
> >>>
> >>>> On 1/1/2020 11:24 AM, Mr Flibble wrote:
> >>>>
> >>>>> Undefined behaviour aside is C++ union type punning an acceptable hack
> >>>>> or not, given that it is legal in C?
> >>>>> If it works on all the compilers I care about does it really matter that
> >>>>> it is *currently* classed as undefined behaviour?
> >>>>> I would say that everyone has "secretly" fucking done it some time or
> >>>>> other so the C++ Standards Committee should get there act together and
> >>>>> legalize it like it has been in C.
> >>>>> Can anyone provide a straight answer to this?
> >>>>
> >>>> Is there some cryptic hidden thing in the standard that just might
> >>>> "allow" for the following code to run without ub?
> >>>
> >>> Possibly.
> >>>
> >>>> ___________________________
> >>>> #include <iostream>
> >>>>
> >>>> struct base
> >>>> {
> >>>>      int p0;
> >>>> };
> >>>
> >>> Standard layout classes have lot of additional guarantees.
> >>>
> >>>> struct object_0
> >>>> {
> >>>>      base b;
> >>>>      int p0;
> >>>> };
> >>>
> >>> Standard layout with common initial sequence with base.
> >>
> >> Unless I'm missing something the two struct types base and object_0
> >> don't have a common initial sequence (or we might say the common
> >> initial sequence is the empty set).  The first member of base is of
> >> type int.  The first member of object_0 is of type base.  These two
> >> types, int and base, are not layout-compatible:  they are not the
> >> same type;  they are not layout-compatible enumerations;  and they
> >> are not layout-compatible standard-layout class types.  Hence there
> >> is no common initial sequence.
> >
> > Address of standard layout object and its first element is required to
> > be same so standard layout struct x and other struct that has  x as
> > first element have the whole x as common initial sequence.
> 
> The first member of struct base is of type 'int'.  The first member of
> struct object_0 is of type 'base'.  The two types, 'int' and 'base',
> are not layout compatible.  Do you agree or disagree?

I disagree. The address of base is required to be address of int as
well as first element of base so these are layout compatible.

> If you agree, then because the types of those members are not layout
> compatible, those members are not part of a common initial sequence.
> Do you agree or disagree?

[toc] | [prev] | [next] | [standalone]


#71317

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-01-13 12:48 -0800
Message-ID<074aa134-b041-43f8-b44e-f6643eee5645@googlegroups.com>
In reply to#71311
Could you please identify the clauses in the standard that define layout
compatibility in terms of addresses? The only ones I can find that seem
relevant specify that layout compatibility depends upon the order and
declared types of the members of structs.

[toc] | [prev] | [next] | [standalone]


#71322

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-13 14:15 -0800
Message-ID<a7279af6-380a-4939-9a4b-c3b8a4648753@googlegroups.com>
In reply to#71317
On Monday, 13 January 2020 22:48:59 UTC+2, James Kuyper  wrote:
> Could you please identify the clauses in the standard that define layout
> compatibility in terms of addresses? The only ones I can find that seem
> relevant specify that layout compatibility depends upon the order and
> declared types of the members of structs.

If a standard-layout class object has any non-static data members, its 
address is the same as the address of its first non-static data member.
[class.mem]24

So address of standard layout class object of type "base" and 
address of standard layout class object whose first non-static
data member is of type "base" are both addresses of object of
type "base". Two standard layout objects of type "base" are
layout compatible, aren't those? 

[toc] | [prev] | [next] | [standalone]


#71328

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-01-13 21:47 -0500
Message-ID<qvja44$ad$1@dont-email.me>
In reply to#71322
On 1/13/20 5:15 PM, Öö Tiib wrote:
> On Monday, 13 January 2020 22:48:59 UTC+2, James Kuyper  wrote:
>> Could you please identify the clauses in the standard that define layout
>> compatibility in terms of addresses? The only ones I can find that seem
>> relevant specify that layout compatibility depends upon the order and
>> declared types of the members of structs.
> 
> If a standard-layout class object has any non-static data members, its 
> address is the same as the address of its first non-static data member.
> [class.mem]24

That's not what I'm looking for. That's a rule that allows you to reach
the conclusion that two objects are at the same address. I'm looking for
the rule who's existence is implied by your argument, which allows you
to take the fact that two struct members must be at the same address,
and from that fact conclude that they are corresponding members of the
common initial sequence of two struct types.

> So address of standard layout class object of type "base" and 
> address of standard layout class object whose first non-static
> data member is of type "base" are both addresses of object of
> type "base". Two standard layout objects of type "base" are
> layout compatible, aren't those?

True - but irrelevant. You've dropped the relevant code, but I'm going
to reinstate it in order to make it clear what I'm referring to.

On 1/2/20 6:39 PM, Chris M. Thomasson wrote:
> struct base
> {
>      int p0;
> };
>
> struct object_0
> {
>      base b;
>      int p0;
> };
>
> struct object_1
> {
>      base b;
>      int p0;
>      int p1;
> };
>
> union object
> {
>      base b;
>      object_0 o0;
>      object_1 o1;
> };
>
>
> int main() {
>      object o;

I'm in perfect agreement that o.b, o.o0.b and o.o1.b all have the same
type, and therefore have layout-compatible types. I'm also in agreement
that all three have the same address. The fact that o.o0.b and o.01.b
have layout compatible types means that it's perfectly safe to write to
o.o0.b.p0, and read from o.o1.b.p0 - the value you read is guaranteed to
be the same as the the value that was written, because of 9.2p19.

However, no similar conclusion can be derived from the fact that o.b is
layout compatible with the other two objects, nor from the fact that it
has the same address as they do. If you feel otherwise, please cite the
rule that allows it.

The first point to note is that in order to apply 9.2p19, the two
structs being compared must be members of the union. So if you're
looking at o.b and o.o0.b, the struct types that you need to compare are
struct base and struct object_0. o.o0.b is not a member of the union -
it's a member of a member of the union, so it's type is not directly
relevant to the question of whether or not 9.2p19 applies.

The second point to note is that the common initial sequence of two
struct types A and B is an ordered list of pairs of members, each pair
containing one non-static data member of struct A, and one non-static
data member of struct B. The list must be in the same order as the
declarations of the members in each struct types, and the members of
each pair must have layout compatible types.

The only member of o.b is named "p0" and has the type "int". There are
two members of o.o0, named "b" and "p0", which have the types "struct
base" and "int" respectively. If you claim that struct base and struct
object_0 have a common initial sequence, then the first and only member
of that common initial sequence would have to be the first member of o.b
(which is o.b.p0) paired up with the first member of o.o0 (which is
o.o0.b). But o.b.p0 has the type "int", while o.o0.b has the type
"struct base". There's no rule that allows you to conclude that any
struct type is layout compatible with any scalar type.

Let me address that last point in more detail. 3.9p11 identifies three
ways that you can reach the conclusion that two types are layout-compatible:

1. The types cv1 T1 and cv2 T2 (where cv1 and cv2 are optionally empty
lists of type qualifiers) are compatible only if T1 and T2 are the same
type. But "int" and "struct base" are not the same type.

2. Two enumerations can be layout compatible if they have the same
underlying type (7.2p9). But neither "int" nor "struct base" is an
enumeration.

3. Two standard-layout class types can be layout compatible (9.2p17) if
they have the same number of non-static data members and each such
member of one struct type is layout-compatible with the corresponding
member of the other struct type. But "int" is not a class type, and
therefore, in particular, cannot qualify as a standard-layout class type.

[toc] | [prev] | [next] | [standalone]


#71331

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-13 23:44 -0800
Message-ID<88c1fbf9-e0ab-483e-8ec5-aa43f07146b0@googlegroups.com>
In reply to#71328
On Tuesday, 14 January 2020 04:47:42 UTC+2, James Kuyper  wrote:
> On 1/13/20 5:15 PM, Öö Tiib wrote:
> > On Monday, 13 January 2020 22:48:59 UTC+2, James Kuyper  wrote:
> >> Could you please identify the clauses in the standard that define layout
> >> compatibility in terms of addresses? The only ones I can find that seem
> >> relevant specify that layout compatibility depends upon the order and
> >> declared types of the members of structs.
> > 
> > If a standard-layout class object has any non-static data members, its 
> > address is the same as the address of its first non-static data member.
> > [class.mem]24
> 
> That's not what I'm looking for. That's a rule that allows you to reach
> the conclusion that two objects are at the same address. I'm looking for
> the rule who's existence is implied by your argument, which allows you
> to take the fact that two struct members must be at the same address,
> and from that fact conclude that they are corresponding members of the
> common initial sequence of two struct types.
> 
> > So address of standard layout class object of type "base" and 
> > address of standard layout class object whose first non-static
> > data member is of type "base" are both addresses of object of
> > type "base". Two standard layout objects of type "base" are
> > layout compatible, aren't those?
> 
> True - but irrelevant. You've dropped the relevant code, but I'm going
> to reinstate it in order to make it clear what I'm referring to.
> 
> On 1/2/20 6:39 PM, Chris M. Thomasson wrote:
> > struct base
> > {
> >      int p0;
> > };
> >
> > struct object_0
> > {
> >      base b;
> >      int p0;
> > };
> >
> > struct object_1
> > {
> >      base b;
> >      int p0;
> >      int p1;
> > };
> >
> > union object
> > {
> >      base b;
> >      object_0 o0;
> >      object_1 o1;
> > };
> >
> >
> > int main() {
> >      object o;
> 
> I'm in perfect agreement that o.b, o.o0.b and o.o1.b all have the same
> type, and therefore have layout-compatible types. I'm also in agreement
> that all three have the same address. The fact that o.o0.b and o.01.b
> have layout compatible types means that it's perfectly safe to write to
> o.o0.b.p0, and read from o.o1.b.p0 - the value you read is guaranteed to
> be the same as the the value that was written, because of 9.2p19.
> 
> However, no similar conclusion can be derived from the fact that o.b is
> layout compatible with the other two objects, nor from the fact that it
> has the same address as they do. If you feel otherwise, please cite the
> rule that allows it.

So o.b, o.o0.b and o.o1.b are all objects of same type at
same storage location but writing to one and reading from other 
is still prohibited? There are no volatile or something like that
in play here, so I am expecting such prohibition to be explicit
in standard. Both Tim and you seem to say that first member of
those being an int somehow causes contradiction but the idea does
not shine thru into my thick skull. :(


> 
> The first point to note is that in order to apply 9.2p19, the two
> structs being compared must be members of the union. So if you're
> looking at o.b and o.o0.b, the struct types that you need to compare are
> struct base and struct object_0. o.o0.b is not a member of the union -
> it's a member of a member of the union, so it's type is not directly
> relevant to the question of whether or not 9.2p19 applies.
> 
> The second point to note is that the common initial sequence of two
> struct types A and B is an ordered list of pairs of members, each pair
> containing one non-static data member of struct A, and one non-static
> data member of struct B. The list must be in the same order as the
> declarations of the members in each struct types, and the members of
> each pair must have layout compatible types.
> 
> The only member of o.b is named "p0" and has the type "int". There are
> two members of o.o0, named "b" and "p0", which have the types "struct
> base" and "int" respectively. If you claim that struct base and struct
> object_0 have a common initial sequence, then the first and only member
> of that common initial sequence would have to be the first member of o.b
> (which is o.b.p0) paired up with the first member of o.o0 (which is
> o.o0.b). But o.b.p0 has the type "int", while o.o0.b has the type
> "struct base". There's no rule that allows you to conclude that any
> struct type is layout compatible with any scalar type.
> 
> Let me address that last point in more detail. 3.9p11 identifies three
> ways that you can reach the conclusion that two types are layout-compatible:
> 
> 1. The types cv1 T1 and cv2 T2 (where cv1 and cv2 are optionally empty
> lists of type qualifiers) are compatible only if T1 and T2 are the same
> type. But "int" and "struct base" are not the same type.
> 
> 2. Two enumerations can be layout compatible if they have the same
> underlying type (7.2p9). But neither "int" nor "struct base" is an
> enumeration.
> 
> 3. Two standard-layout class types can be layout compatible (9.2p17) if
> they have the same number of non-static data members and each such
> member of one struct type is layout-compatible with the corresponding
> member of the other struct type. But "int" is not a class type, and
> therefore, in particular, cannot qualify as a standard-layout class type.

[toc] | [prev] | [next] | [standalone]


#71336

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-01-14 08:26 -0500
Message-ID<qvkfhr$ns7$1@dont-email.me>
In reply to#71331
On 1/14/20 2:44 AM, Öö Tiib wrote:
> On Tuesday, 14 January 2020 04:47:42 UTC+2, James Kuyper  wrote:
...>> On 1/2/20 6:39 PM, Chris M. Thomasson wrote:
>>> struct base
>>> {
>>>      int p0;
>>> };
>>>
>>> struct object_0
>>> {
>>>      base b;
>>>      int p0;
>>> };
>>>
>>> struct object_1
>>> {
>>>      base b;
>>>      int p0;
>>>      int p1;
>>> };
>>>
>>> union object
>>> {
>>>      base b;
>>>      object_0 o0;
>>>      object_1 o1;
>>> };
>>>
>>>
>>> int main() {
>>>      object o;
>>
>> I'm in perfect agreement that o.b, o.o0.b and o.o1.b all have the same
>> type, and therefore have layout-compatible types. I'm also in agreement
>> that all three have the same address. The fact that o.o0.b and o.01.b
>> have layout compatible types means that it's perfectly safe to write to
>> o.o0.b.p0, and read from o.o1.b.p0 - the value you read is guaranteed to
>> be the same as the the value that was written, because of 9.2p19.
>>
>> However, no similar conclusion can be derived from the fact that o.b is
>> layout compatible with the other two objects, nor from the fact that it
>> has the same address as they do. If you feel otherwise, please cite the
>> rule that allows it.
> 
> So o.b, o.o0.b and o.o1.b are all objects of same type at
> same storage location but writing to one and reading from other 
> is still prohibited? There are no volatile or something like that
> in play here, so I am expecting such prohibition to be explicit
> in standard. Both Tim and you seem to say that first member of
> those being an int somehow causes contradiction but the idea does
> not shine thru into my thick skull. :(

To put this in proper perspective, let's start by considering a single
variable.

The C++ standard says that "An instance of each object with automatic
storage duration (3.7.3) is associated with each entry into its
block. Such an object exists and retains its last-stored value during
the execution of the block and while the block is suspended (by a call
of a function or receipt of a signal)." (1.9p7).

I could not locate wording in the C++ standard that says the anything
comparable about objects with other storage durations - which surprises
me. I suspect that I've missed something. For comparison, the C standard
says "An object ... retains its last-stored value throughout its
lifetime." (C2011 6.2.4p4) without restricting that guarantee to objects
with any particular storage duration. For objects with automatic storage
duration, "during the execution  of the block and while the block is
suspended" corresponds to the lifetime of that object, so the C and C++
standards agree for such objects.

Retaining their last-stored value is an essential feature of usable
variables. I'm going to go ahead on the assumption that C++ does
actually say this somewhere for other storage durations, and I just
missed it. Alternatively, you can assume that what I'm saying below only
applies to objects with automatic storage duration (which would render
objects with other storage durations essentially unusable).

Implementations of C++ typically store an object in particular locations
in RAM, but that memory location does not always contain the last-stored
value of that object. Often, the last-stored value currently resides
only in one or more registers somewhere. This is allowed by the as-if
rule. When the last-stored value of a variable is needed, it doesn't
matter whether the compiler retrieves that value from memory or from a
register, so long as the location that it retrieves it from does in fact
contain the last-stored value. It's up to the compiler to keep track of
where the last-stored value is currently stored, and so long as it does
so correctly, the as-if rule allows this.
I don't mean to imply that register/memory issues are the entire reason
for the rules I'm discussing.  Transfers between memory and register are
allowed precisely because (and only insofar as) the C++ standard fails
to say anything to prevent it. I'm just using such issues as a simple,
easy-to-understand example of the kinds of things governed by these rules.

Here's the key point: the different members of a union are considered to
be distinct objects that just happen to be stored in the same location.
For example, given

  union { int i; float f; }u;

an implementation can treat u.i and u.f as if they were distinct
variables, despite the fact that they sit in the same location in
memory. It can keep track of whether u.i is stored in the location
pointed at by &u.i, or in an integer register. It can keep track of
whether u.f is stored in the location pointed at by &u.f or in a
floating point register. However, since it's undefined behavior to read
a different member of a union than the one that was last written to, an
implementation is NOT required to coordinate transfers between u.i and a
register with transfers between u.f and a register. Therefore, if you
write to u.i, that written value might still be in a register at the
time that subsequent code retrieves u.f from memory. Alternatively, if
the value of u.i does get moved to memory, a read of u.f might retrieve
the value last stored in u.f, which is still in a register somewhere.
When more complex objects are in the union, such as objects of struct
type, the ways in which accesses to members of different structs can
interfere with each other get even more complicated.

This anarchy is the normal case for accesses to union members, but
9.2p19 provides an exception to this anarchy for the common initial
sequence of two struct types, so long as those struct types are members
of the same union. If you write a value to a member in the common
initial sequence using one of those two struct types, and read from the
corresponding member of the other struct type, the value read must match
the value written. An implementation is still free to store that value
either in the object itself, or in a register, but it must store and
retrieve that value from the correct location, regardless of which of
the two struct types is used to write it, and regardless of which of the
two struct types is used to read it.

Therefore, you're relying upon the guarantee provided by 9.2p19 in order
to perform such accesses. And the conditions for the applicability of
9.2p19 are not met by o.b.p0, for the reasons I gave above in my earlier
message. Since the common initial sequence is determined entirely by the
membership relationships and types of the relevant objects, and not by
their addresses, the fact that o.b.p0 and o.o0.b.p0 are stored in the
same location does not guarantee that 9.2p19 covers those two objects.

[toc] | [prev] | [next] | [standalone]


#71341

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-01-14 07:30 -0800
Message-ID<86a76qgin8.fsf@linuxsc.com>
In reply to#71311
Tiib writes:

> On Monday, 13 January 2020 19:02:00 UTC+2, Tim Rentsch  wrote:

[context:  this code

    struct base {
         int p0;
    };

    struct object_0 {
         base b;
         int p0;
    };

]

>> The first member of struct base is of type 'int'.  The first member of
>> struct object_0 is of type 'base'.  The two types, 'int' and 'base',
>> are not layout compatible.  Do you agree or disagree?
>
> I disagree.  The address of base is required to be address of int as
> well as first element of base so these are layout compatible.

In N4659, section 6.9 paragraph 11 defines the term 'layout
compatible'.  The definition says (leaving out the cv's) that two
types T1 and T2 are layout compatible if

   (a) T1 and T2 are the same type,

   (b) T1 and T2 are layout-compatible enumerations, or

   (c) T1 and T2 are layout-compatible standard-layout class types.

When T1 is 'int' and T2 is 'base' (aka 'struct base'), which of these
categories do you think applies?

[toc] | [prev] | [next] | [standalone]


#71345

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-14 09:11 -0800
Message-ID<21725e19-05c0-4267-be45-a9aa249ce436@googlegroups.com>
In reply to#71341
On Tuesday, 14 January 2020 17:30:46 UTC+2, Tim Rentsch  wrote:
> Tiib writes:
> 
> > On Monday, 13 January 2020 19:02:00 UTC+2, Tim Rentsch  wrote:
> 
> [context:  this code
> 
>     struct base {
>          int p0;
>     };
> 
>     struct object_0 {
>          base b;
>          int p0;
>     };
> 
> ]
> 
> >> The first member of struct base is of type 'int'.  The first member of
> >> struct object_0 is of type 'base'.  The two types, 'int' and 'base',
> >> are not layout compatible.  Do you agree or disagree?
> >
> > I disagree.  The address of base is required to be address of int as
> > well as first element of base so these are layout compatible.
> 
> In N4659, section 6.9 paragraph 11 defines the term 'layout
> compatible'.  The definition says (leaving out the cv's) that two
> types T1 and T2 are layout compatible if
> 
>    (a) T1 and T2 are the same type,
> 
>    (b) T1 and T2 are layout-compatible enumerations, or
> 
>    (c) T1 and T2 are layout-compatible standard-layout class types.
> 
> When T1 is 'int' and T2 is 'base' (aka 'struct base'), which of these
> categories do you think applies?

T1 is also 'base' so (a) applies.

[toc] | [prev] | [next] | [standalone]


#71353

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-01-14 21:52 -0500
Message-ID<qvluop$kbi$1@dont-email.me>
In reply to#71345
On 1/14/20 12:11 PM, Öö Tiib wrote:
> On Tuesday, 14 January 2020 17:30:46 UTC+2, Tim Rentsch  wrote:
>> Tiib writes:
>>
>>> On Monday, 13 January 2020 19:02:00 UTC+2, Tim Rentsch  wrote:
...
>>>> struct object_0 is of type 'base'.  The two types, 'int' and 'base',
>>>> are not layout compatible.  Do you agree or disagree?
>>>
>>> I disagree.  The address of base is required to be address of int as
>>> well as first element of base so these are layout compatible.
>>
>> In N4659, section 6.9 paragraph 11 defines the term 'layout
>> compatible'.  The definition says (leaving out the cv's) that two
>> types T1 and T2 are layout compatible if
>>
>>    (a) T1 and T2 are the same type,
>>
>>    (b) T1 and T2 are layout-compatible enumerations, or
>>
>>    (c) T1 and T2 are layout-compatible standard-layout class types.
>>
>> When T1 is 'int' and T2 is 'base' (aka 'struct base'), which of these
>> categories do you think applies?
> 
> T1 is also 'base' so (a) applies.

No, it isn't. He asked you whether int and struct base are layout
compatible. In terms of his subsequent discussion, that means that T1 is
"int", and nothing else, while T2 is "struct base", and nothing else.
What makes you think you can just randomly replace the correct type with
a different type?

[toc] | [prev] | [next] | [standalone]


#71355

FromÖö Tiib <ootiib@hot.ee>
Date2020-01-14 23:15 -0800
Message-ID<c27299b9-0087-406f-8d2c-e3e59f7f3645@googlegroups.com>
In reply to#71353
On Wednesday, 15 January 2020 04:52:19 UTC+2, James Kuyper  wrote:
> On 1/14/20 12:11 PM, Öö Tiib wrote:
> > On Tuesday, 14 January 2020 17:30:46 UTC+2, Tim Rentsch  wrote:
> >> Tiib writes:
> >>
> >>> On Monday, 13 January 2020 19:02:00 UTC+2, Tim Rentsch  wrote:
> ...
> >>>> struct object_0 is of type 'base'.  The two types, 'int' and 'base',
> >>>> are not layout compatible.  Do you agree or disagree?
> >>>
> >>> I disagree.  The address of base is required to be address of int as
> >>> well as first element of base so these are layout compatible.
> >>
> >> In N4659, section 6.9 paragraph 11 defines the term 'layout
> >> compatible'.  The definition says (leaving out the cv's) that two
> >> types T1 and T2 are layout compatible if
> >>
> >>    (a) T1 and T2 are the same type,
> >>
> >>    (b) T1 and T2 are layout-compatible enumerations, or
> >>
> >>    (c) T1 and T2 are layout-compatible standard-layout class types.
> >>
> >> When T1 is 'int' and T2 is 'base' (aka 'struct base'), which of these
> >> categories do you think applies?
> > 
> > T1 is also 'base' so (a) applies.
> 
> No, it isn't. He asked you whether int and struct base are layout
> compatible. In terms of his subsequent discussion, that means that T1 is
> "int", and nothing else, while T2 is "struct base", and nothing else.
> What makes you think you can just randomly replace the correct type with
> a different type?

I agree that int and base are not layout compatible standard layout
class types. But it is struct base whose first element that int is
and that base is standard layout class type layout compatible with
base. 

Yes, it may be that there are some kind of optimization opportunities
when to ignore that the two bases are at same offset and so reorder
reads from and writes to those. Since standard can be (apparently)
interpreted in a way that the two bases are unrelated and such
optimization is allowed then writing to one and reading from other
should not be used anyway.

[toc] | [prev] | [next] | [standalone]


#71480

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-01-21 02:03 -0800
Message-ID<86r1ztjfdu.fsf@linuxsc.com>
In reply to#71345
Tiib writes:

> On Tuesday, 14 January 2020 17:30:46 UTC+2, Tim Rentsch  wrote:
>
>> Tiib writes:
>>
>>> On Monday, 13 January 2020 19:02:00 UTC+2, Tim Rentsch  wrote:
>>
>> [context:  this code
>>
>>     struct base {
>>          int p0;
>>     };
>>
>>     struct object_0 {
>>          base b;
>>          int p0;
>>     };
>>
>> ]
>>
>>>> The first member of struct base is of type 'int'.  The first member of
>>>> struct object_0 is of type 'base'.  The two types, 'int' and 'base',
>>>> are not layout compatible.  Do you agree or disagree?
>>>
>>> I disagree.  The address of base is required to be address of int as
>>> well as first element of base so these are layout compatible.
>>
>> In N4659, section 6.9 paragraph 11 defines the term 'layout
>> compatible'.  The definition says (leaving out the cv's) that two
>> types T1 and T2 are layout compatible if
>>
>>    (a) T1 and T2 are the same type,
>>
>>    (b) T1 and T2 are layout-compatible enumerations, or
>>
>>    (c) T1 and T2 are layout-compatible standard-layout class types.
>>
>> When T1 is 'int' and T2 is 'base' (aka 'struct base'), which of these
>> categories do you think applies?
>
> T1 is also 'base' so (a) applies.

No, it isn't.  It appears that either you haven't been listening
or you aren't thinking clearly.

[toc] | [prev] | [next] | [standalone]


#71291

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-01-11 07:28 -0800
Message-ID<868sme2err.fsf@linuxsc.com>
In reply to#70986
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:

> On 1/1/2020 11:24 AM, Mr Flibble wrote:
>
>> Undefined behaviour aside is C++ union type punning an acceptable
>> hack or not, given that it is legal in C?
>> If it works on all the compilers I care about does it really matter
>> that it is *currently* classed as undefined behaviour?
>> I would say that everyone has "secretly" fucking done it some time
>> or other so the C++ Standards Committee should get there act
>> together and legalize it like it has been in C.
>> Can anyone provide a straight answer to this?
>
> Is there some cryptic hidden thing in the standard that just might
> "allow" for the following code to run without ub?
> ___________________________
> #include <iostream>
>
> struct base
> {
>     int p0;
> };
>
> struct object_0
> {
>     base b;
>     int p0;
> };
>
> struct object_1
> {
>     base b;
>     int p0;
>     int p1;
> };
>
> union object
> {
>     base b;
>     object_0 o0;
>     object_1 o1;
> };
>
>
> int main() {
>     object o;
>
>     o.b.p0 = 41;
>     o.o0.b.p0 += 1;
>     o.o1.b.p0 += 1;
>
>     // humm
>     int r = o.b.p0; // ub...
>
>     std::cout << "r = " << r << "\n";
>
>     return 0;
> }
> ___________________________
>
>
> Wrt POD and a common base object on each sub-object in a union, well
> does it bite the dust with UB?

I believe this runs afoul of the rules for common initial
sequences, because type 'base' has as its first member a type
that is not layout compatible with the type of the first members
of object_0 and object_1.  Either just use an unadorned int for
the first members of object_0 and object_1:

    struct object_0 {
        int p0;
        ...
    };

    struct object_1 {
        int p0;
        ...
    };

or wrap the 'base' member of the union in a struct

    union object {
        struct { base b; } tag;
        object_0 o0;
        object_1 o1;
    };

with corresponding changes to the accessing code.

I haven't looked carefully at the updating part of the question.
My guess is if you want to be really sure the code isn't doing
anything "bad" it should be coded more carefully.  But that is
just a guess, so take it for what it's worth.

[toc] | [prev] | [next] | [standalone]


#71300

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2020-01-11 20:40 -0800
Message-ID<qve7vf$gs5$1@gioia.aioe.org>
In reply to#71291
On 1/11/2020 7:28 AM, Tim Rentsch wrote:
> "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
> 
>> On 1/1/2020 11:24 AM, Mr Flibble wrote:
>>
>>> Undefined behaviour aside is C++ union type punning an acceptable
>>> hack or not, given that it is legal in C?
>>> If it works on all the compilers I care about does it really matter
>>> that it is *currently* classed as undefined behaviour?
>>> I would say that everyone has "secretly" fucking done it some time
>>> or other so the C++ Standards Committee should get there act
>>> together and legalize it like it has been in C.
>>> Can anyone provide a straight answer to this?
>>
>> Is there some cryptic hidden thing in the standard that just might
>> "allow" for the following code to run without ub?
>> ___________________________
>> #include <iostream>
>>
>> struct base
>> {
>>      int p0;
>> };
>>
>> struct object_0
>> {
>>      base b;
>>      int p0;
>> };
>>
>> struct object_1
>> {
>>      base b;
>>      int p0;
>>      int p1;
>> };
>>
>> union object
>> {
>>      base b;
>>      object_0 o0;
>>      object_1 o1;
>> };
>>
>>
>> int main() {
>>      object o;
>>
>>      o.b.p0 = 41;
>>      o.o0.b.p0 += 1;
>>      o.o1.b.p0 += 1;
>>
>>      // humm
>>      int r = o.b.p0; // ub...
>>
>>      std::cout << "r = " << r << "\n";
>>
>>      return 0;
>> }
>> ___________________________
>>
>>
>> Wrt POD and a common base object on each sub-object in a union, well
>> does it bite the dust with UB?
> 
> I believe this runs afoul of the rules for common initial
> sequences, because type 'base' has as its first member a type
> that is not layout compatible with the type of the first members
> of object_0 and object_1.

Everything boils down to an int. Therefore, the common initial sequence 
is an int. It should work. Its all POD, everything has that common int, 
even in struct base. Afaict, The first int, in base, or anything in 
union object has the same address. union object::b has the same address 
as union object::o1::base. Its all POD.

   Either just use an unadorned int for
> the first members of object_0 and object_1:
> 
>      struct object_0 {
>          int p0;
>          ...
>      };
> 
>      struct object_1 {
>          int p0;
>          ...
>      };
> 
> or wrap the 'base' member of the union in a struct
> 
>      union object {
>          struct { base b; } tag;
>          object_0 o0;
>          object_1 o1;
>      };
> 
> with corresponding changes to the accessing code.
> 
> I haven't looked carefully at the updating part of the question.
> My guess is if you want to be really sure the code isn't doing
> anything "bad" it should be coded more carefully.  But that is
> just a guess, so take it for what it's worth.
> 

[toc] | [prev] | [next] | [standalone]


#71301

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-01-12 20:16 -0500
Message-ID<qvggdo$pe0$1@dont-email.me>
In reply to#71300
On 1/11/20 11:40 PM, Chris M. Thomasson wrote:
> On 1/11/2020 7:28 AM, Tim Rentsch wrote:
>> "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
...
>>> #include <iostream>
>>>
>>> struct base
>>> {
>>>      int p0;
>>> };
>>>
>>> struct object_0
>>> {
>>>      base b;
>>>      int p0;
>>> };
>>>
>>> struct object_1
>>> {
>>>      base b;
>>>      int p0;
>>>      int p1;
>>> };
>>>
>>> union object
>>> {
>>>      base b;
>>>      object_0 o0;
>>>      object_1 o1;
>>> };
>>>
>>>
>>> int main() {
>>>      object o;
>>>
>>>      o.b.p0 = 41;
>>>      o.o0.b.p0 += 1;
>>>      o.o1.b.p0 += 1;
>>>
>>>      // humm
>>>      int r = o.b.p0; // ub...
>>>
>>>      std::cout << "r = " << r << "\n";
>>>
>>>      return 0;
>>> }
>>> ___________________________
>>>
>>>
>>> Wrt POD and a common base object on each sub-object in a union, well
>>> does it bite the dust with UB?
>>
>> I believe this runs afoul of the rules for common initial
>> sequences, because type 'base' has as its first member a type
>> that is not layout compatible with the type of the first members
>> of object_0 and object_1.
> 
> Everything boils down to an int. Therefore, the common initial sequence 
> is an int. It should work. Its all POD, everything has that common int, 
> even in struct base. ...

In a standard-layout union with an active member (9.5) of struct type
T1, it is permitted to read a non-static data member m of another union
member of struct type T2 provided m is part of the common initial
sequence of T1 and T2." (9.2p19).

"The common initial sequence of two standard-layout struct (Clause 9)
types is the longest sequence of non-static data members and bit-fields
in declaration order, starting with the first such entity in each of the
structs, such that corresponding entities have layout-compatible types
and either neither entity is a bit-field or both are bit-fields with the
same width." (9.2p16). "common initial sequence" is italicized in that
text, an ISO convention identifying this sentence as the official
definition of that term. Nothing in that definition allow you to match
up o.b.p0 with o.o0.b.p0 in order to qualify as having a common initial
sequence. It's the corresponding members that have to have
layout-compatible types, and "struct base" and "int" don't.

> ... Afaict, The first int, in base, or anything in 
> union object has the same address. union object::b has the same address 
> as union object::o1::base. Its all POD.

That's true - but this isn't just about the address. This rule covers
additional members of the common initial sequence, even though there's
no other reason why they'd be required to have the same address. And
when the conditions for this guarantee fail to be met, the fact the
o.b.p0 and o.o0.b.p0 must be at the same address doesn't make it safe to
use one of those expressions if the corresponding union member is not
the currently active one. This rule is, at least as much as anything
else, about when aliasing is and is not permitted. A conforming
implementation of C++ is allowed to notice that o.b.p0 and o.o0.b.p0 are
accessed through different members of the same union, which don't have a
common initial sequence, and is therefore allowed to not bother checking
whether or not they occupy the same location in memory. In particular, a
change to one of them might be kept in a register, rather than being
written to memory, and a subsequent access to the other one could
retrieve the old value stored in memory, rather than the new value
that's currently stored in a register.

[toc] | [prev] | [next] | [standalone]


Page 6 of 7 — ← Prev page 1 2 3 4 5 [6] 7  Next page →

Back to top | Article view | comp.lang.c++


csiph-web