0

I am a beginner programmer in C. I have a structure which has different data types as members like int, float, bool. I am trying to initialize this struct to a value of 0.0 during initialization and also during run time for an Embedded application. I am doing member by member initialization. I cannot use memset() function as it increments the pointer by 2 bytes. I am wondering if there's an efficient way of doing this initialization.

Ex:

typedef struct _ABC_
{
       float a;
       float b;
       float c;
       int x;
       bool_t y;
}ABC;
ram surada
  • 61
  • 6

2 Answers2

7

I cannot use memset() function as it increments the pointer by 2 bytes.

Yes, you can use memset() - it doesn't "increment" anything:

ABC abc;
memset(&abc, 0, sizeof(ABC)); //Sets sizeof(ABC) bytes to 0

The only problem with this approach is that setting all bits of floating point numbers does not mean, that their value will be equal to 0. Especially, as IEEE 754 states:

-0 and +0 are distinct values, though they both compare as equal.

So indeed, their internal representation needs to be different (and thus, neither of them may have all bits set to 0). In case of IEEE 754 it just accidentally happens, that zeroed value is equal to 0. Other FP representations may (and probably will) differ in that matter.

Because of that, you may want to initialize this struct as every POD-type:

ABC abc =
{
    0.0f, //a
    0.0f, //b
    0.0f, //c
    0,    //x
    false //y
};

Or even better:

ABC abc =
{
    0 //initializes all members to 0
};

Last example works only, if all members of this struct can be initialized with value of integral type (which is true in this particular case).

Mateusz Grzejek
  • 11,698
  • 3
  • 32
  • 49
  • 1
    `memset(..., 0, ...)` will just clear all bits. That does not necessarily mean anything other than integer types will be set to their null value (0.0 or null pointer). For Float, 0.0 with all bits zeroed happens to be true for IEEE754, but those are not required by the standard; especially on embedded systems, they may use a different format. For pointer, the standard only requires a null pointer not to have a valid pointer value; it does not require "all bits zero". You should state that at least for a proper answer. – too honest for this site Aug 01 '15 at 13:45
  • @Olaf Yes, indeed. Done. – Mateusz Grzejek Aug 01 '15 at 13:53
  • 1
    FYI: "it just accidentally happens, that zeroed value is equal to 0". That was no accident, but clever design. In the old days, floating point units were rare, so floats had to be often calculated in software. making +0.0 equal to integer 0 allowed to use the same test and quick clear memory (yes, `memset`). My point is actually non-IEEE754 formats. The standard allows this. And you did not even mention pointers. – too honest for this site Aug 01 '15 at 14:03
  • @Olaf Question was about a particular case, which does not involve pointers. We both know, that it is impossible to cover whole topic in every answer to a simple problem. I mentioned, that non-IEEE formats may not interpret zeroed FP variable as 0. Also, I wrote *it just accidentally happens* with cursive, because there was no accident, that's the point. Also, I suggested, that the best solution in this case would be POD-style initialization, which also covers pointers, since they can be initialized with `0`, which is then automatically converted to a proper pointer type. – Mateusz Grzejek Aug 01 '15 at 14:14
  • I agree (but we both also know, that most non-trivial C programs will use pointers eventually). Using `0` to initialize pointers is old-style C++ and was never recommended in C. In C++ you use `nullptr`, in C `NULL` which will likely be `(void *)0`. – too honest for this site Aug 01 '15 at 14:18
-4

The ISO c and ISO c++ standard say that setting all bits zero does not guarantee the floating point value to be zero. You have to explicitly assign 0.0 to it.

Also, There is no exact floating point zero. There are five distinct numerical ranges that single-precision floating-point numbers are not able to represent:

  • Negative numbers less than -(2-2e-23) × 2e127 (negative overflow)
  • Negative numbers greater than -2e-149 (negative underflow)
  • Zero
  • Positive numbers less than 2e-149 (positive underflow)
  • Positive numbers greater than (2-2e-23) × 2e127 (positive overflow)

Suggestion:

#define INFINITESIMAL 2e-149

ABC abc =
{
    INFINITESIMAL,
    INFINITESIMAL,
    INFINITESIMAL,
    0,
    false,  // You may preserve the comma at the end of the list in ISO C99
};
Lv Zheng
  • 316
  • 2
  • 6
  • 1
    Reference needed for *There is no exact floating point zero.* – Yu Hao Aug 01 '15 at 12:21
  • 1
    This is absolutely wrong. In context of initialization, value will be implicitly converted as required. See [this](http://stackoverflow.com/questions/5199338/what-is-the-significance-of-0-0f-when-initializing-in-c) and [this](http://stackoverflow.com/questions/1384434/c-difference-between-0-and-0-0) question. – Mateusz Grzejek Aug 01 '15 at 12:23
  • @LvZheng You should probably read more about initialization and conversions between numerical values. `float f = 0` and `float f = 0.0f` are equal. What you stated is simply *incorrect*. – Mateusz Grzejek Aug 01 '15 at 13:44
  • 1
    IEEE754 floats are designed such that "all bits zero" is `+0.0` actually. So that way there is no problem. However, the C standard does not enforce it (just strongly suggests). Using magic numbers (the `#define`) for implementation specifics is is careless at best. `0.0` would be perfect valid to set the float to `0.0` (surprise, surprise). – too honest for this site Aug 01 '15 at 14:12