Is It Wise to Ignore Gcc/Clang's "-Wmissing-Braces" Warning

Is it wise to ignore gcc/clang's -Wmissing-braces warning?

-Wmissing-braces will no longer be enabled in GCC's -Wall (for C++ mode), as of 4.8, for precisely the reason you describe. For current versions of GCC, either disable or ignore the warning, the code you have is written the way it should be.

The warning is probably meant to cover code such as

struct A { int a; int b; };
struct B { A a; int b; };
B b = {
1,
2 // initialises b.a.b, not b.b
};

However, IMHO, that is already handled well enough by -Wmissing-field-initializers, which does not warn about your original code.

Why is clang++ warning suggest braces around initialization of subobject [-Wmissing-braces]?

This should be a bug: https://llvm.org/bugs/show_bug.cgi?id=21629.

See also Is it wise to ignore gcc/clang's "-Wmissing-braces" warning?.

How to repair warning: missing braces around initializer?

Yes, this appears to be related to GCC bug 53119. It goes away if you change the C declaration to {{0}}. Your options are:

  1. Ignore the warning.
  2. Manipulate the C code after generation to have {{0}} instead of {0} on that line using sed or the like.
  3. Declare the array extern in Vala, and write the C definition elsewhere. (The permanent version of #2.)
  4. Do something like struct foo { int bar; Position positions[8]; } static foo position_holder and {0} will then be initialising position_holder.bar which is fine and the warning goes away.

How to fix C++ gcc compile warning for padding of struct

Just disable the warning (or - well, don't enable it, I don't know of any warning set like -Wall or -Wextra that includes it). -Wpadded is not meant to be always enabled, unless you want to always manually specify the necessary padding explicitly.

-Wpadded

Warn if padding is included in a structure, either to align an element of the structure or to align the whole structure. Sometimes when this happens it is possible to rearrange the fields of the structure to reduce the padding and so make the structure smaller.

(emphasis added)

This is one case where it's not possible. long double is 10 bytes, and it requires 16 bytes alignment (4 on x86 Linux); QString is effectively a pointer, so it needs 8 bytes alignment (4 on 32 bit Linux). You can swap them however you want, but if you want to keep natural alignment (and thus best performance) you'll either get 6 + 8 bytes of padding or 8 + 6 bytes of padding.

In general, adding padding is not a problem, happens all the time and there are cases such as this when it's unavoidable. The general rule to keep it at a minimum is to place elements in order of decreasing alignment requirements, but again, it cannot always be avoided.

As mentioned above, the only alternative (keeping good alignment) is making the padding explicit, but it doesn't make much sense (unless you are designing a file format or something and you want to make everything explicit, but in that case you wouldn't use a QString and would pack to 1 byte).

struct stance {
long double interval;
char unused0[6];
QString name;
char unused1[8];
};

Why is GCC warning me this line is misleadingly indented as if it were guarded by an if?

There were spaces used to indent the conditional line 49, but a tab was used to indent line 51.

Tabs are viewed as 8 spaces by GCC. The compiler mistakenly thought that it was aligned with the if statement, even though it didn't seem like that in the editor. It is another reason to be consistent with white space indentation (e.g., by avoiding using any tabs in source code).

How can I turn on (literally) ALL of GCC's warnings?

You can't.

The manual for GCC 4.4.0 is only comprehensive for that version, but it does list all the possible warnings for 4.4.0. They're not all on the page you link to though. For instance, some language-specific options are on the pages for C++ options or Objective-C options. To find them all, you're better off looking at the Options Summary

Turning on everything would include -Wdouble-promotion which is only relevant on CPUs with a 32-bit single-precision floating-point unit which implements float in hardware, but emulates double in software. Doing calculations as double would use the software emulation and be slower. That's relevant for some embedded CPUs, but completely irrelevant for modern desktop CPUs with hardware support for 64-bit floating-point.

Another warning that's not usually useful is -Wtraditional, which warns about perfectly well formed code that has a different meaning (or doesn't work) in traditional C, e.g., "string " "concatenation", or ISO C function definitions! Do you really care about compatibility with 30 year old compilers? Do you really want a warning for writing int inc(int i) { return i+1; }?

I think -Weffc++ is too noisy to be useful. It's based on the outdated first edition of Effective C++ and warns about constructs which are perfectly valid C++ (and for which the guidelines changed in later editions of the book). I don't want to be warned that I haven't initialized a std::string member in my constructor; it has a default constructor that does exactly what I want. Why should I write m_str() to call it? The -Weffc++ warnings that would be helpful are too difficult for the compiler to detect accurately (giving false negatives), and the ones that aren't useful, such as initializing all members explicitly, just produce too much noise, giving false positives.

Luc Danton provided a great example of useless warnings from -Waggregate-return that almost certainly never makes sense for C++ code.

I.e., you don't really want all warnings; you just think you do.

Go through the manual, read about them, decide which you might want to enable, and try them. Reading your compiler's manual is a Good ThingTM anyway, taking a shortcut and enabling warnings you don't understand is not a very good idea, especially if it's to avoid having to RTFM.

Anyone who just turns on everything is probably either doing so because they're clueless because or a pointy-haired boss said "no warnings."

Some warnings are important, and some aren't. You have to be discriminating or you mess up your program. Consider, for instance, -Wdouble-promotion. If you're working on an embedded system you might want this; if you're working on a desktop system you probably don't. And do you want -Wtraditional? I doubt it.

See also -Wall-all to enable all warnings which is closed as WONTFIX.

In response to DevSolar's complaint about makefiles needing to use different warnings depending on compiler version, if -Wall -Wextra isn't suitable then it's not difficult to use compiler-specific and version-specific CFLAGS:

compiler_name := $(notdir $(CC))
ifeq ($(compiler_name),gcc)
compiler_version := $(basename $(shell $(CC) -dumpversion))
endif
ifeq ($(compile_name),clang)
compiler_version := $(shell $(CC) --version | awk 'NR==1{print $$3}')
endif
# ...
wflags.gcc.base := -Wall -Wextra
wflags.gcc.4.7 := -Wzero-as-null-pointer-constant
wflags.gcc.4.8 := $(wflags.gcc.4.7)
wflags.clang.base := -Wall -Wextra
wflags.clang.3.2 := -Weverything
CFLAGS += $(wflags.$(compiler_name).base) $(wflags.$(compiler_name).$(compiler_version))

Why does gcc complain about my loops?

From gcc manual:

-funsafe-loop-optimizations

This option tells the loop optimizer to assume that loop indices do not overflow, and that loops with nontrivial exit condition are not infinite. This enables a wider range of loop optimizations even if the loop optimizer itself cannot prove that these assumptions are valid. If you use -Wunsafe-loop-optimizations, the compiler warns you if it finds this kind of loop.

Thus, apparently, the implementation of range-for loop in the compiler is somehow broken in that it triggers this warning. You could either disable this particular warning or disable this particular optimization... I would advise the latter as it is unclear to me whether the optimization is actually done or not when the warning is triggered.

warning C5246: the initialization of a subobject should be wrapped in braces

Visual Studio 2019 has the CWG defect #1270 and offers the old initialization behaviour.

std::array is defined as an aggregate that contains another aggregate.

C++ 17 Standard (11.6.1 Aggregates)

12 Braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the elements of a subaggregate; it is erroneous for there to be more initializer-clauses than elements. If, however, the initializer-list for a subaggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the elements of the subaggregate; any remaining initializer-clauses are left to initialize the next element of the aggregate of which the current subaggregate is an element.

You may imagine std::array<A, 2> as

struct Array {
A sub[2];
};

According to the quote Array a {{x, y}} is correct, but obsolete, the inner braces is aggregate initialization of the enclosed array.

Useful thread Why is the C++ initializer_list behavior for std::vector and std::array different?.

How to disable GCC warnings for a few lines of code

It appears this can be done. I'm unable to determine the version of GCC that it was added, but it was sometime before June 2010.

Here's an example:

#pragma GCC diagnostic error "-Wuninitialized"
foo(a); /* error is given for this one */

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
foo(b); /* no diagnostic for this one */
#pragma GCC diagnostic pop

foo(c); /* error is given for this one */
#pragma GCC diagnostic pop

foo(d); /* depends on command line options */


Related Topics



Leave a reply



Submit