9

I have the following code in a C++ file:

#include <sys/socket.h>

// ...
void someFunc() {
    struct msghdr msg = {0};  // <<< Uninitialized member here
}

When I compile with g++ using -Wall -Wextra, I get warnings:

error: missing initializer for member 'msghdr::msg_namelen'
...same for several other fields

My problem is this: I can't explicitly initialize all the fields, because I don't know what fields will exist (cross-platform) in a struct msghdr. The struct doesn't have a default constructor, since it's a C struct. I was under the impression that the = {0} form led to zero-initialization of all fields (which would be fine for me), but the g++ error message suggests not.

What are my options here?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tim Martin
  • 3,618
  • 6
  • 32
  • 43
  • possible duplicate of [Why is the compiler throwing this warning: "missing initializer"? Isn't the structure initialized?](http://stackoverflow.com/questions/1538943/why-is-the-compiler-throwing-this-warning-missing-initializer-isnt-the-stru) – ergosys Jun 20 '12 at 22:01

4 Answers4

11

Do this:

void someFunc()
{
    msghdr msg = {};  // <<< All members zero-initialized
}

The g++ -Wextra warning level is IMHO not very useful.

The code that you have is also formally OK for a "C struct", in standardeese known as POD (plain old data structure). But your code explicitly initializes the first member with 0. That won't necessarily work for an aggregate that isn't POD, e.g., with a std::string as the first member, while the pure {} will work also for that.

In passing, often a POD like the one you're dealing with has a byte count as the first member, and then you can do like …

void foo()
{
    SomePODStruct o = {sizeof(o)};    // The other members zero-initialized.
}

Perhaps add a STATIC_ASSERT that the byte count member is first (at offset 0).

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
4

This should work:

memset(&msg, 0, sizeof(msg));
Eric Fortin
  • 7,533
  • 2
  • 25
  • 33
  • fix your typo and I'll remove my answer, you beat me to it by seconds! :) – Nim Jan 24 '11 at 13:42
  • I hate `memset`. It is bug prone (easy to use wrong order of arguments) and verbose. It is not C++sy and even in this case using C proper use of braces does the job: https://godbolt.org/z/7zf6fKvKn – Marek R Jul 28 '22 at 15:31
2

The specific warning flag that causes this is -Wmissing-field-initializers, which is turned on as part of -Wextra. The simplest way to avoid this (bogus) warning is therefore to use -Wno-missing-field-initializers.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tim Martin
  • 3,618
  • 6
  • 32
  • 43
1

If you can't live with the warning and/or don't want to disable the warning, then I think it will have to be explicit initialisation via e.g. memset:

memset(&msg, 0, sizeof(msg));
Paul R
  • 208,748
  • 37
  • 389
  • 560