[cfe-dev] warning request: partial array initialisation

Chandler Carruth chandlerc at google.com
Tue Jun 19 10:56:39 PDT 2012


On Tue, Jun 19, 2012 at 10:36 AM, Matthieu Monrocq <
matthieu.monrocq at gmail.com> wrote:

>
>
> On Tue, Jun 19, 2012 at 7:01 PM, Chris Hall <
> chris.hall.list at highwayman.com> wrote:
>
>> Chandler Carruth wrote (on Tue 19-Jun-2012 at 17:50 +0100)
>> >
>> > On Tue, Jun 19, 2012 at 1:20 AM, Jay Foad <jay.foad at gmail.com> wrote:
>> ....
>> >>  #define N 8
>> >>  const int a[N] = { 3, 1, 4, 1, 5, 9, 2 };
>> >> warning: some but not all array elements initialised
>> ...
>> > Maybe someone has clever ideas about how to syntactically differentiate
>> > between these two use cases?
>>
>>   const int a[N] = { ..... } __attribute__((all_explicitly_initialised))
>>
>> Chris
>>
>>
>> Would a heuristic be acceptable ?
>
> If the number of initializer is in [.9 * N, N) then it looks likely it is
> a bug. The .9 factor could probably benefit from some tuning, maybe as low
> as .5 would pass.
>

I really dislike this style of diagnostic, because it's essentially
impossible to tell innocent users what to do when the warning fires on
their correct code.

user: Why am I getting this warning? My code is correct!
me: Well, we have a heuristic to try to detect when there is a bug, and it
triggers on your code.
user: But my code doesn't have a bug. The standard says right there that
this is a supported use case.
me: I understand, but there is code that looks *exactly* like your code
that is in fact a bug.
user: So what rule do I use when writing code so I don't tickle this
warning when my code is correct, but I get the warning when it has a bug?
me: ...

I have no answer for that last question. I can't say '0.9 * N' for lots of
reasons. We would change it to 0.8 at some point, users can't count past
10, and they certainly can't multiply or divide, and so the rule wouldn't
help. I can't say "follow the standard" because the standard directly
contradicts this warning. I can't realistically say "always initialize
every element" because often that's either impractical, impossible, or just
plain poor style. (Hence the standard allowing this partial formation...)

When we're designing warnings that try to catch bugs, we need to focus on
getting the warning into a state that is easier to explain and cope with
for our users. For example:

1) A warning that is *always* a bug in the code is easy: the user can't
really complain, their code is simply wrong.
2) A warning that directs innocent users to some alternate syntax which
hase equivalent semantics but is more explicit / clear / less bug-prone.

#2 is really hard to get right, and we should be overly conservative in
employing it. Here are a few cases where I think we do a good job here:
- Demanding explicit '()'s to group mixed '&&' and '||' operations, due to
poor understanding of their precedence
- Warning about functions declared at block scope unless they are
explicitly marked with 'extern' due to their confusion with declaring a
variable and calling its constructor (most vexing parse, etc).
- Warning when a literal is converted to an unexpected type, such as
converting 'false' to a null pointer.

In all of these cases, there is a significantly more clear way to express
the intent of the programmer, and we have a very large body of evidence
that these warnings almost unilaterally fire on buggy or incorrect code
based on the experience turning them on across large code bases. Just
having one of these isn't enough, it's important to have both. It's also
important to be able to argue for the more clear formation through the
presence of *bugs*, not through a stylistic or aesthetic preference.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120619/f9247e4e/attachment.html>


More information about the cfe-dev mailing list