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


Groups > comp.lang.c++ > #6213

Re: unions

From Edek <edek.pienkowski@gmail.com>
Newsgroups comp.lang.c++
Subject Re: unions
Date 2011-06-04 22:34 +0200
Organization ATMAN - ATM S.A.
Message-ID <ise4sq$8e7$1@node2.news.atman.pl> (permalink)
References <iscfn1$keo$8@reader1.panix.com> <isdrr3$urc$1@node2.news.atman.pl> <4DEA75DF.6010402@sh.cvut.cz>

Show all headers | View raw


On 06/04/2011 08:13 PM, Vaclav Haisman wrote:
> Edek wrote, On 4.6.2011 19:59:
>>    Am I missing something about them?  I
>>> started to have deep doubts about what I thought I knew.
>>>
>>
>> Other things aside, by the standard unions are the only
>> possibility to alias two non-char types without breaking
>> optimisations. Maybe void* is another and a couple of
>> other strange cases. Don't ask me about where it is in the
>> standard; I just know that it is a pain to find bugs
>> caused by wrong casting coupled with unpredictable optimisation
>> results (UB caused by casts really, unions are safe).
> Unions are not safe. You cannot write using one union member and read using
> another. It is only GCC extension that it works but the standard does not
> allow it, AFAIK.
>

I think it here depends what is precisely meant. Code:

typedef union {
    short    _s;
    UU*     _ptr;
} UU;

1) Safe:

short ok(UU *p1, UU* p2)
{
    short tmp = p2->_s; // a
    p1->_ptr = p2; // b, by different type


    return tmp + p1->_ptr->_s; //c

// I think this is what I meant as legal
// all access by union
// compiler knows a),b),c) may alias, same type accessed (UU)
// which causes a reread of p2->_s at c), because it may have
// been overwritten by b). No warnings.

	movzwl	(%rsi), %eax  a)
	movq	%rsi, (%rdi)  b)
	addw	(%rsi), %ax   c) <--- reload of _s
	ret
// Note: no reordering either, in case rdi == rsi
}

2) Also safe

short alsoOk (UU* p1)
{
     UU u; // not an aliasing problem, local copy accessed
     u._ptr = p1[23]->_ptr;
     return u._s;

	movq	184(%rdi), %rax // Trivial
	ret

};

3)

short foo (UU *uu, int *p2)
{
// not allowed. Casting to union in main (below) does not mean
// the same as my above 'all access by union'

     short tmp = uu->_s;

     p2[42] = 0; // may overwrite uu->_s

     return tmp + uu->_s; // will compiler reread uu->_s? No...

	movzwl	(%rdi), %eax
	movl	$0, 168(%rsi)
	addl	%eax, %eax  // tmp + tmp really

}

The output of the below is:
$ ./main
Is 84
  should be: 42
$


#include <iostream>

using namespace std;

extern short foo (UU*,int*);

int main ()
{
     int * ints = new int[100];

     for (int i = 0; i < 100; i++) ints[i]=i;

     int& ourVal = ints[42];

     short shouldBe = ((UU*)&ourVal)->_s; // warns

     cout << "Is " << foo ((UU*)&ourVal, ints) // warns
          << endl;

     shouldBe += ((UU*)&ourVal)->_s; // warns

     cout << " should be: " << shouldBe << endl;

     delete [] ints;
     return -1;
}



Is the extension you are referring to calling foo when UU is

typedef union uu {
    short     _s;
    union uu  _ptr;
    int       _int;
};

? Then generated code is fine.

Correct? I'm not a language lawyer. BTW, the effect depends on whether
foo and main are compiled together or separately, and whether they are
compiled with -fPIC or not, and possibly other options.

Edek

Back to comp.lang.c++ | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

unions Ruben Safir <ruben@mrbrklyn.com> - 2011-06-04 05:26 +0000
  Re: unions Ian Collins <ian-news@hotmail.com> - 2011-06-04 17:38 +1200
    Re: unions Ruben Safir <ruben@mrbrklyn.com> - 2011-06-04 05:45 +0000
      Re: unions Ian Collins <ian-news@hotmail.com> - 2011-06-04 18:04 +1200
        Re: unions Ruben Safir <ruben@mrbrklyn.com> - 2011-06-04 06:13 +0000
  Re: unions Öö Tiib <ootiib@hot.ee> - 2011-06-04 04:54 -0700
  Re: unions Edek <edek.pienkowski@gmail.com> - 2011-06-04 19:59 +0200
    Re: unions Vaclav Haisman <v.haisman@sh.cvut.cz> - 2011-06-04 20:13 +0200
      Re: unions Edek <edek.pienkowski@gmail.com> - 2011-06-04 22:34 +0200
        Re: unions Vaclav Haisman <v.haisman@sh.cvut.cz> - 2011-06-05 07:29 +0200
  Re: unions Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-06-09 09:19 +0000
  Re: unions Keith <kbelder@gmail.com> - 2011-06-09 11:17 -0700
    Re: unions Victor Bazarov <v.bazarov@comcast.invalid> - 2011-06-09 14:29 -0400
    Re: unions Edek <edek.pienkowski@gmail.com> - 2011-06-10 13:16 +0200

csiph-web