Path: csiph.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Bo Persson Newsgroups: comp.lang.c++ Subject: Re: This will work or not? Date: Wed, 31 Aug 2016 18:53:00 +0200 Lines: 72 Message-ID: References: <20160831145918.45a0c396@maxa-pc> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Trace: individual.net pdYQmixtbetL2bDOpyeaqQ3Ziri8dFX1OeVV80abYVlMvFeozy Cancel-Lock: sha1:Kddsp568+e1azTaPnLKU7vPi40c= User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 In-Reply-To: Xref: csiph.com comp.lang.c++:44639 On 2016-08-31 15:20, David Brown wrote: > On 31/08/16 14:59, Melzzzzz wrote: >> Code in question is like this: >> >> struct Problem{ >> uint32_t a; >> uint32_t b; >> uint64_t c; >> uint32_t d; >> bool check_it() { >> for (uint32_t* i = &a;i != &d; ++i) >> if (*i>0) return true; >> return false; >> } >> >> }; >> >> I am not sure if this will work, so if someone has clear explanation >> why it will work (or not) , I would be grateful. >> > > I don't think you are guaranteed that a, b, c, and d follow each other > in the structure layout (though it is very likely to be the case). With > a pointer to a single item &a, incrementing the pointer is undefined > behaviour - as is accessing *i. And accessing the uint64_t member using > an uint32_t* pointer contradicts aliasing restrictions. > > All in all, the compiler is free to assume that this code is full of > undefined behaviour, therefore you don't really care what it does - > therefore it can all be optimised to "return true", "return false", or > even "launch nasal daemons". (This last option is legal for the > compiler, but thankfully unlikely in practice.) > > You can make it legal with: > > struct Problem { > union { > struct { > uint32_t a; > uint32_t b; > uint64_t c; > uint32_t d; > } > uint32_t as_array[5]; > } > bool check_it() { > for (uint32_t* i = &as_array[0]; i != &as_array[4]; ++i) > if (*i > 0) return true; > return false; > } > } > > (Any issues regarding anonymous unions/structs are left as an exercise > for the reader :-) > This might work in C, but a problem is that the C++ standard says: 9.3 Unions "In a union, a non-static data member is active if its name refers to an object whose lifetime has begun and has not ended (3.8). At most one of the non-static data members of an object of union type can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time. " So, if the struct with a, b, c, and d is active, as_array is not "stored" and cannot be read. You can't read an object that isn't there! Bo Persson