1

Possible Duplicate:
Set all bytes of int to (unsigned char)0, guaranteed to represent zero?

I have the following anonymous union inside a struct:

union
{
    unsigned value;
    char name[4];
};

Can I replace the following code:

name[0] = 0;
name[1] = 0;
name[2] = 0;
name[3] = 0;

With the following code?

value = 0;
Community
  • 1
  • 1
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • I think it boils down to this - http://stackoverflow.com/questions/11373203/accessing-inactive-union-member-undefined - right? – Luchian Grigore Jul 13 '12 at 11:20
  • @LuchianGrigore no. This is writing. – R. Martinho Fernandes Jul 13 '12 at 11:21
  • @R.MartinhoFernandes yes, but I'm assuming he later wants to also read from it, otherwise there would be no need for the zeroing, right? – Luchian Grigore Jul 13 '12 at 11:22
  • If it's only a matter of byte representation and writing, this question is very relevant: **[Set all bytes of int to (unsigned char)0, guaranteed to represent zero?](http://stackoverflow.com/questions/11138188/set-all-bytes-of-int-to-unsigned-char0-guaranteed-to-represent-zero)** – Filip Roséen - refp Jul 13 '12 at 11:27
  • 1
    @LuchianGrigore I don't want to go into this again, and I'm off to lunch, but you can alias anything with a pointer or reference to char. I've mentioned this before here: http://stackoverflow.com/a/10272228/46642 This is a contentious topic, so don't take my word as proof. – R. Martinho Fernandes Jul 13 '12 at 11:28
  • Basically, I don't see why `*reinterpret_cast(&value)` is ok, but `name[0]` is UB. – R. Martinho Fernandes Jul 13 '12 at 11:33
  • @LuchianGrigore, no it doesn't boil down to that question there, because here it is asked for C++ and C at the same time. They are different with that respect. – Jens Gustedt Jul 13 '12 at 13:03

6 Answers6

2

In your simple case it's the same, but only because (most likely) int (and unsigned is short for unsigned int) is 32 bits (i.e. four bytes). If the array is larger, or int is only 16 bits it will not be the same.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

I think this code is better:

memset(name, 0, max(sizeof(name), sizeof(int)));
Dmitry Poroh
  • 3,705
  • 20
  • 34
1

In C you'd better do

union
{
   char name[sizeof(unsigned)];
   unsigned value;
};

Now an implicit initializer, e.g if you initialize the surrounding struct, will always initialize your name field to all 0. And provided unsigned has no padding bits (which is very likely) an initialization or assignment of 0 to value will also always zero out name.

Rules for C++ are different, it seems that there reading from a different field that you have written to is UB.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

between

name[0] = 0;

and

name[1] = 0;

and

name[2] = 0;

and

name[3] = 0;

other functions can change other bytes. So,

value = 0; 

is more secure i think

huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97
0

Yes, but only if sizeof(unsigned)==4.

qehgt
  • 2,972
  • 1
  • 22
  • 36
-1

Yes, that is right if you're on a 64-bit machine. If not you will overwrite the first 2 characters from name, because on 32-bit machines unsigned's size is 2 byte not 4 (or higher).

qwertz
  • 14,614
  • 10
  • 34
  • 46