From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Stefan Hajnoczi <stefanha@redhat.com>
Cc: qemu-devel@nongnu.org, "Hanna Czenczek" <hreitz@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Richard Henderson" <richard.henderson@linaro.org>,
"Thomas Huth" <thuth@redhat.com>,
"Alex Bennée" <alex.bennee@linaro.org>
Subject: Re: [PATCH] docs/style: allow C99 mixed declarations
Date: Mon, 5 Feb 2024 17:41:02 +0000 [thread overview]
Message-ID: <ZcEdrp-y5YFsfir4@redhat.com> (raw)
In-Reply-To: <20240205171819.474283-1-stefanha@redhat.com>
On Mon, Feb 05, 2024 at 12:18:19PM -0500, Stefan Hajnoczi wrote:
> C99 mixed declarations support interleaving of local variable
> declarations and code.
>
> The coding style "generally" forbids C99 mixed declarations with some
> exceptions to the rule. This rule is not checked by checkpatch.pl and
> naturally there are violations in the source tree.
>
> While contemplating adding another exception, I came to the conclusion
> that the best location for declarations depends on context. Let the
> programmer declare variables where it is best for legibility. Don't try
> to define all possible scenarios/exceptions.
IIRC, we had a discussion on this topic sometime last year, but can't
remember what the $SUBJECT was, so I'll just repeat what I said then.
Combining C99 mixed declarations with 'goto' is dangerous.
Consider this program:
$ cat jump.c
#include <stdlib.h>
int main(int argc, char**argv) {
if (getenv("SKIP"))
goto target;
char *foo = malloc(30);
target:
free(foo);
}
$ gcc -Wall -Wuninitialized -o jump jump.c
$ SKIP=1 ./jump
free(): invalid pointer
Aborted (core dumped)
-> The programmer thinks they have initialized 'foo'
-> GCC thinks the programmer has initialized 'foo'
-> Yet 'foo' is not guaranteed to be initialized at 'target:'
Given that QEMU makes heavy use of 'goto', allowing C99 mixed
declarations exposes us to significant danger.
Full disclosure, GCC fails to diagnmose this mistake, even
with a decl at start of 'main', but at least the mistake is
now more visible to the programmer.
Fortunately with -fanalyzer GCC can diagnose this:
$ gcc -fanalyzer -Wall -o jump jump.c
jump.c: In function ‘main’:
jump.c:12:3: warning: use of uninitialized value ‘foo’ [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
12 | free(foo);
| ^~~~~~~~~
‘main’: events 1-5
|
| 6 | if (getenv("SKIP"))
| | ~
| | |
| | (3) following ‘true’ branch...
| 7 | goto target;
| | ~~~~
| | |
| | (4) ...to here
| 8 |
| 9 | char *foo = malloc(30);
| | ^~~
| | |
| | (1) region created on stack here
| | (2) capacity: 8 bytes
|......
| 12 | free(foo);
| | ~~~~~~~~~
| | |
| | (5) use of uninitialized value ‘foo’ here
...but -fanalyzer isn't something we have enabled by default, it
is opt-in. I'm also not sure how comprehensive the flow control
analysis of -fanalyzer is ? Can we be sure it'll catch these
mistakes in large complex functions with many code paths ?
Even if the compiler does reliably warn, I think the code pattern
remains misleading to contributors, as the flow control flaw is
very non-obvious.
Rather than accept the status quo and remove the coding guideline,
I think we should strengthen the guidelines, such that it is
explicitly forbidden in any method that uses 'goto'. Personally
I'd go all the way to -Werror=declaration-after-statement, as
while C99 mixed decl is appealing, it isn't exactly a game
changer in improving code maintainability.
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
> docs/devel/style.rst | 20 --------------------
> 1 file changed, 20 deletions(-)
>
> diff --git a/docs/devel/style.rst b/docs/devel/style.rst
> index 2f68b50079..80c4e4df52 100644
> --- a/docs/devel/style.rst
> +++ b/docs/devel/style.rst
> @@ -199,26 +199,6 @@ Rationale: a consistent (except for functions...) bracing style reduces
> ambiguity and avoids needless churn when lines are added or removed.
> Furthermore, it is the QEMU coding style.
>
> -Declarations
> -============
> -
> -Mixed declarations (interleaving statements and declarations within
> -blocks) are generally not allowed; declarations should be at the beginning
> -of blocks. To avoid accidental re-use it is permissible to declare
> -loop variables inside for loops:
> -
> -.. code-block:: c
> -
> - for (int i = 0; i < ARRAY_SIZE(thing); i++) {
> - /* do something loopy */
> - }
> -
> -Every now and then, an exception is made for declarations inside a
> -#ifdef or #ifndef block: if the code looks nicer, such declarations can
> -be placed at the top of the block even if there are statements above.
> -On the other hand, however, it's often best to move that #ifdef/#ifndef
> -block to a separate function altogether.
> -
> Conditional statements
> ======================
>
> --
> 2.43.0
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2024-02-05 17:42 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-05 17:18 [PATCH] docs/style: allow C99 mixed declarations Stefan Hajnoczi
2024-02-05 17:41 ` Daniel P. Berrangé [this message]
2024-02-05 17:55 ` Peter Maydell
2024-02-05 18:12 ` Samuel Tardieu
2024-02-05 19:06 ` Stefan Hajnoczi
2024-02-05 19:17 ` Daniel P. Berrangé
2024-02-06 5:53 ` Markus Armbruster
2024-02-07 5:28 ` Philippe Mathieu-Daudé
2024-02-07 7:37 ` Markus Armbruster
2024-02-05 23:17 ` Alex Bennée
2024-02-06 13:48 ` Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZcEdrp-y5YFsfir4@redhat.com \
--to=berrange@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=armbru@redhat.com \
--cc=hreitz@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=stefanha@redhat.com \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.