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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).