Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #6213
| 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> |
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
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