-1

I've seen two different ways to fill a char[] with 0 (in this example, upon initialization):

/* method 1 */
char foo[1024] = {0};

/* method 2 */
char foo[1024];
memset(foo, '\0', sizeof(foo));

What are the main differences between the two codes? How do they differ in functionality, etc?

MD XF
  • 7,860
  • 7
  • 40
  • 71
  • 1
    "*How do they differ in functionality,*" which functionality are you referring to? – alk Dec 17 '16 at 08:13
  • @alk Do they achieve the exact same end goal? If not, what's the difference? – MD XF Dec 17 '16 at 08:14
  • Yes, after the call to `memset` Case 2's `foo` carries the same content as Case 1's `foo`, namely all `0`s. – alk Dec 17 '16 at 08:18
  • @alk Okay thanks; and just wondering, is one considered better practice than the other? – MD XF Dec 17 '16 at 08:20
  • Possible duplicate of [Difference in initializing and zeroing an array in c/c++?](http://stackoverflow.com/questions/453432/difference-in-initializing-and-zeroing-an-array-in-c-c) – Wasi Ahmad Dec 17 '16 at 08:21
  • @WasiAhmad Darn. Hey, except mine is specifically about C, since I don't like c++... so maybe it's different? – MD XF Dec 17 '16 at 08:22
  • "*better practice*" Having all variables initialised tends to end up in more robust code, where as performance wise placing initialisations all over the place might be sub optimal. – alk Dec 17 '16 at 08:24
  • 2
    And now come on, please redesign *Redesign*. As it stands, it clutters the GUI. – alk Dec 17 '16 at 08:25
  • the post was for both c and c++. so, this is clearly a duplicate question. – Wasi Ahmad Dec 17 '16 at 08:30
  • @WasiAhmad C and C++ are **not** the same language. – MD XF Dec 17 '16 at 08:31
  • as if i don't know :v – Wasi Ahmad Dec 17 '16 at 08:32
  • @Rͧeͤͤͧ̊͗dě͒͗̇̐͒s̆͊̓͋͌i͂ͨg̈̏̚n-- since you bring up C++: in C++ you can also zero-initialize an array with `char foo[1024] = {};`, but in C the use of empty braces is a syntax error. – ad absurdum Dec 17 '16 at 10:32

4 Answers4

2

What are the main differences between the two codes?

In case 1 the array is zeroed out from the moment it can be used, as it got initialised.

In case 2 its content is well defined only after the call to memset().

The essential difference is that for case 2 there is is gap where foo's content is "garbage". This isn't the case for case 1.

alk
  • 69,737
  • 10
  • 105
  • 255
1

The first way is generally better, since it zero initializes all members. Mem setting to 0 is not always the same as zero initializing, particularly for floating point and pointer members, which may have 0 values that aren't all bits zero.

Performance wise, I don't know which would be faster, you'd have to measure it. By the way, you can use 0 instead of '\0' in memset.

memset(foo, 0, sizeof(foo));
Wasi Ahmad
  • 35,739
  • 32
  • 114
  • 161
  • Can you provide an example of a case where initializing an array of, e.g., floating point zeros, would not set all bits to 0? Floating point zero in IEEE 754 is represented by all bits set to 0 (or sign bit set to 1). – ad absurdum Dec 17 '16 at 12:15
  • @DavidBowling i agree with your point. While answering this question, i didn't consider only 0, rather any float value. For example, 9.0. In java, sometimes i have seen 9.0 is considered as 8.999999999999999.... So, its little bit risky to use memset (according to me) for initialization for float values. – Wasi Ahmad Dec 17 '16 at 20:03
  • I am not entirely convinced about floating point values here, not that this is a bad idea, I will think about that some more. But, as far as initializing an array of say, `NULL` pointers, it seems like a good idea to choose the initializer over `memset()`, since the `NULL` macro is implementation defined. Interesting points. – ad absurdum Dec 17 '16 at 20:26
  • I am just preferring one over another, i am not saying any one of them is a bad idea, please note that. Moreover, i don't disagree with your point. My only preference is - avoiding `memset()` in case of floating point values. – Wasi Ahmad Dec 17 '16 at 20:39
  • @DavidBowling a non-IEEE754 system for example, or for pointers a system where address zero is expected to be used, so null pointers are represented by some other pattern – M.M Dec 18 '16 at 20:43
1

The effect of these two codes is the same. Probably a compiler will generate the same assembly in both cases. However the first one is easier to read and maintain.

There is no possible way you can accidentally write the wrong length of data with the first one.

Further, the = { 0 }; idiom can be used to initialize all named arrays and structures: integers get 0 value, floating point get 0.0 , and pointers get a null pointer. Only the first of those three things is guaranteed for the memset version.

So if you are writing portable code, you'll need to use = { 0 } sometimes anyway -- so you may as well use it every time.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • I was convinced about `NULL` pointers from the beginning, and after further reflection have come around on the matter of initializers with floating point numbers. You and @WasiAhmad raised a good point; this is one of the reasons I love SO. Always something new to learn :) – ad absurdum Dec 18 '16 at 21:13
0
/* method 1 */
char foo[1024] = {0};

in method 1, the setting of the array occurs at program load time, usually from a literal and can only occur once for each entry into the 'scope' of the array.

/* method 2 */
char foo[1024];
memset(foo, '\0', sizeof(foo));

in method 2, the setting of the array occurs at runtime, consumes runtime CPU cycles, and can occur as many times as needed.

user3629249
  • 16,402
  • 1
  • 16
  • 17