diff mbox series

revision: use C99 declaration of variable in for() loop

Message ID xmqqpmr2j5lq.fsf_-_@gitster.g (mailing list archive)
State New, archived
Headers show
Series revision: use C99 declaration of variable in for() loop | expand

Commit Message

Junio C Hamano Nov. 15, 2021, 6:27 a.m. UTC
There are certain C99 features that might be nice to use in our code
base, but we've hesitated to do so in order to avoid breaking
compatibility with older compilers. But we don't actually know if
people are even using pre-C99 compilers these days.

One way to figure that out is to introduce a very small use of a
feature, and see if anybody complains, and we've done so to probe
the portability for a few features like "trailing comma in enum
declaration", "designated initializer for struct", and "designated
initializer for array".  A few years ago, we tried to use a handy

    for (int i = 0; i < n; i++)
	use(i);

to introduce a new variable valid only in the loop, but found that
some compilers we cared about didn't like it back then.  Two years
is a long-enough time, so let's try it agin.

If this patch can survive a few releases without complaint, then we
can feel more confident that variable declaration in for() loop is
supported by the compilers our user base use.  And if we do get
complaints, then we'll have gained some data and we can easily
revert this patch.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 revision.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

Comments

Martin Ågren Nov. 15, 2021, 7:44 a.m. UTC | #1
On Mon, 15 Nov 2021 at 07:30, Junio C Hamano <gitster@pobox.com> wrote:
>
> There are certain C99 features that might be nice to use in our code
> base, but we've hesitated to do so in order to avoid breaking
> compatibility with older compilers. But we don't actually know if
> people are even using pre-C99 compilers these days.

> is a long-enough time, so let's try it agin.

s/agin/again/

>  void show_object_with_name(FILE *out, struct object *obj, const char *name)
>  {
> -       const char *p;
> -
>         fprintf(out, "%s ", oid_to_hex(&obj->oid));
> -       for (p = name; *p && *p != '\n'; p++)
> +       for (const char *p = name; *p && *p != '\n'; p++)
>                 fputc(*p, out);
>         fputc('\n', out);
>  }

This seems like a stable-enough function for this experiment.

Similar to 765dc16888 ("git-compat-util: always enable variadic macros",
2021-01-28), maybe we should add something like

  /*
   * This "for (const char *p = ..." is made as a first step towards
   * making use of such declarations elsewhere in our codebase.  If
   * it causes compilation problems on your platform, please report
   * it to the Git mailing list at git@vger.kernel.org.
   */

to reduce the chance of someone patching it up locally thinking that
it's just a one-off.

Martin
brian m. carlson Nov. 15, 2021, 10:26 p.m. UTC | #2
On 2021-11-15 at 06:27:45, Junio C Hamano wrote:
> There are certain C99 features that might be nice to use in our code
> base, but we've hesitated to do so in order to avoid breaking
> compatibility with older compilers. But we don't actually know if
> people are even using pre-C99 compilers these days.
> 
> One way to figure that out is to introduce a very small use of a
> feature, and see if anybody complains, and we've done so to probe
> the portability for a few features like "trailing comma in enum
> declaration", "designated initializer for struct", and "designated
> initializer for array".  A few years ago, we tried to use a handy
> 
>     for (int i = 0; i < n; i++)
> 	use(i);
> 
> to introduce a new variable valid only in the loop, but found that
> some compilers we cared about didn't like it back then.  Two years
> is a long-enough time, so let's try it agin.

I think you absolutely need a compiler option for this to work on older
systems.  Many of those compilers support C99 just fine but need an
option to enable it.

I think this could go on top of my patch, though.

> If this patch can survive a few releases without complaint, then we
> can feel more confident that variable declaration in for() loop is
> supported by the compilers our user base use.  And if we do get
> complaints, then we'll have gained some data and we can easily
> revert this patch.
> 
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
>  revision.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/revision.c b/revision.c
> index 9dff845bed..44492f2c02 100644
> --- a/revision.c
> +++ b/revision.c
> @@ -43,10 +43,8 @@ static inline int want_ancestry(const struct rev_info *revs);
>  
>  void show_object_with_name(FILE *out, struct object *obj, const char *name)
>  {
> -	const char *p;
> -
>  	fprintf(out, "%s ", oid_to_hex(&obj->oid));
> -	for (p = name; *p && *p != '\n'; p++)
> +	for (const char *p = name; *p && *p != '\n'; p++)
>  		fputc(*p, out);
>  	fputc('\n', out);
>  }
> -- 
> 2.34.0-rc2-165-g9b3c04af29
>
Junio C Hamano Nov. 16, 2021, 8:29 a.m. UTC | #3
Martin Ågren <martin.agren@gmail.com> writes:

> On Mon, 15 Nov 2021 at 07:30, Junio C Hamano <gitster@pobox.com> wrote:
>>
>> There are certain C99 features that might be nice to use in our code
>> base, but we've hesitated to do so in order to avoid breaking
>> compatibility with older compilers. But we don't actually know if
>> people are even using pre-C99 compilers these days.
>
>> is a long-enough time, so let's try it agin.
>
> s/agin/again/
>
>>  void show_object_with_name(FILE *out, struct object *obj, const char *name)
>>  {
>> -       const char *p;
>> -
>>         fprintf(out, "%s ", oid_to_hex(&obj->oid));
>> -       for (p = name; *p && *p != '\n'; p++)
>> +       for (const char *p = name; *p && *p != '\n'; p++)
>>                 fputc(*p, out);
>>         fputc('\n', out);
>>  }
>
> This seems like a stable-enough function for this experiment.

Yup, the callers and the implementation are from several years ago,
if I am not mistaken.

> Similar to 765dc16888 ("git-compat-util: always enable variadic macros",
> 2021-01-28), maybe we should add something like
>
>   /*
>    * This "for (const char *p = ..." is made as a first step towards
>    * making use of such declarations elsewhere in our codebase.  If
>    * it causes compilation problems on your platform, please report
>    * it to the Git mailing list at git@vger.kernel.org.
>    */
>
> to reduce the chance of someone patching it up locally thinking that
> it's just a one-off.

Probably.  It would help people to refrain from copying and pasting
this and making it harder to back out, too.
Phillip Wood Nov. 17, 2021, 11:03 a.m. UTC | #4
Hi Junio

On 15/11/2021 06:27, Junio C Hamano wrote:
> There are certain C99 features that might be nice to use in our code
> base, but we've hesitated to do so in order to avoid breaking
> compatibility with older compilers. But we don't actually know if
> people are even using pre-C99 compilers these days.
> 
> One way to figure that out is to introduce a very small use of a
> feature, and see if anybody complains, and we've done so to probe
> the portability for a few features like "trailing comma in enum
> declaration", "designated initializer for struct", and "designated
> initializer for array".  A few years ago, we tried to use a handy
> 
>      for (int i = 0; i < n; i++)
> 	use(i);
> 
> to introduce a new variable valid only in the loop, but found that
> some compilers we cared about didn't like it back then.  Two years
> is a long-enough time, so let's try it agin.
> 
> If this patch can survive a few releases without complaint, then we
> can feel more confident that variable declaration in for() loop is
> supported by the compilers our user base use.  And if we do get
> complaints, then we'll have gained some data and we can easily
> revert this patch.

I like the idea of using a specific test balloon for the features that 
we want to use but wont this one break the build for anyone doing 'make 
DEVELOPER=1' because -Wdeclaration-after-statement will error out. I 
think we could wrap the loop in gcc's warning pragmas to avoid that.

Best Wishes

Phillip

> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> ---
>   revision.c | 4 +---
>   1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/revision.c b/revision.c
> index 9dff845bed..44492f2c02 100644
> --- a/revision.c
> +++ b/revision.c
> @@ -43,10 +43,8 @@ static inline int want_ancestry(const struct rev_info *revs);
>   
>   void show_object_with_name(FILE *out, struct object *obj, const char *name)
>   {
> -	const char *p;
> -
>   	fprintf(out, "%s ", oid_to_hex(&obj->oid));
> -	for (p = name; *p && *p != '\n'; p++)
> +	for (const char *p = name; *p && *p != '\n'; p++)
>   		fputc(*p, out);
>   	fputc('\n', out);
>   }
>
Ævar Arnfjörð Bjarmason Nov. 17, 2021, 12:39 p.m. UTC | #5
On Wed, Nov 17 2021, Phillip Wood wrote:

> Hi Junio
>
> On 15/11/2021 06:27, Junio C Hamano wrote:
>> There are certain C99 features that might be nice to use in our code
>> base, but we've hesitated to do so in order to avoid breaking
>> compatibility with older compilers. But we don't actually know if
>> people are even using pre-C99 compilers these days.
>> One way to figure that out is to introduce a very small use of a
>> feature, and see if anybody complains, and we've done so to probe
>> the portability for a few features like "trailing comma in enum
>> declaration", "designated initializer for struct", and "designated
>> initializer for array".  A few years ago, we tried to use a handy
>>      for (int i = 0; i < n; i++)
>> 	use(i);
>> to introduce a new variable valid only in the loop, but found that
>> some compilers we cared about didn't like it back then.  Two years
>> is a long-enough time, so let's try it agin.
>> If this patch can survive a few releases without complaint, then we
>> can feel more confident that variable declaration in for() loop is
>> supported by the compilers our user base use.  And if we do get
>> complaints, then we'll have gained some data and we can easily
>> revert this patch.
>
> I like the idea of using a specific test balloon for the features that
> we want to use but wont this one break the build for anyone doing
> 'make DEVELOPER=1' because -Wdeclaration-after-statement will error
> out. I think we could wrap the loop in gcc's warning pragmas to avoid
> that.

Good point.

Overall something that brings us to the end-state 765dc168882
(git-compat-util: always enable variadic macros, 2021-01-28) brought us
to is probably better, i.e. something you can work around by defining or
undefining a macro via a Makefile parameter, instead of needing to patch
git's sources.
SZEDER Gábor Nov. 17, 2021, 10:30 p.m. UTC | #6
On Wed, Nov 17, 2021 at 11:03:58AM +0000, Phillip Wood wrote:
> Hi Junio
> 
> On 15/11/2021 06:27, Junio C Hamano wrote:
> > There are certain C99 features that might be nice to use in our code
> > base, but we've hesitated to do so in order to avoid breaking
> > compatibility with older compilers. But we don't actually know if
> > people are even using pre-C99 compilers these days.
> > 
> > One way to figure that out is to introduce a very small use of a
> > feature, and see if anybody complains, and we've done so to probe
> > the portability for a few features like "trailing comma in enum
> > declaration", "designated initializer for struct", and "designated
> > initializer for array".  A few years ago, we tried to use a handy
> > 
> >      for (int i = 0; i < n; i++)
> > 	use(i);
> > 
> > to introduce a new variable valid only in the loop, but found that
> > some compilers we cared about didn't like it back then.  Two years
> > is a long-enough time, so let's try it agin.
> > 
> > If this patch can survive a few releases without complaint, then we
> > can feel more confident that variable declaration in for() loop is
> > supported by the compilers our user base use.  And if we do get
> > complaints, then we'll have gained some data and we can easily
> > revert this patch.
> 
> I like the idea of using a specific test balloon for the features that we
> want to use but wont this one break the build for anyone doing 'make
> DEVELOPER=1' because -Wdeclaration-after-statement will error out. I think
> we could wrap the loop in gcc's warning pragmas to avoid that.

The scope of the loop variable is limited to the loop, so I don't
think this is considered as declaration after statement, just like
other variable declarations in limited scopes that are abundant in
Git's codebase, e.g.:

  printf("...");
  if (var) {
      int a;
      ...
  }

FWIW, I've spent some time with Compiler Explorer compiling a for loop
initial declaration after a statement with '-std=c99 -Werror
-Wdeclaration-after-statement', and none of them complained (though
there were some that didn't understand the '-std=c99' or '-Wdecl...'
options or couldn't compile it for some other reason).
Junio C Hamano Nov. 18, 2021, 7:09 a.m. UTC | #7
Phillip Wood <phillip.wood123@gmail.com> writes:

> I like the idea of using a specific test balloon for the features that
> we want to use but wont this one break the build for anyone doing
> 'make DEVELOPER=1' because -Wdeclaration-after-statement will error
> out.

I think you are missing '?' at the end of the sentence, but the
answer is "no, at least not for me".

    # pardon my "make" wrapper; it is to pass DEVELOPER=1 etc. to
    # the underlying "make" command.
    $ Meta/Make V=1 revision.o
    cc -o revision.o -c -MF ./.depend/revision.o.d -MQ revision.o -MMD -MP  -Werror -Wall -pedantic -Wpedantic -Wdeclaration-after-statement -Wformat-security -Wold-style-definition -Woverflow -Wpointer-arith -Wstrict-prototypes -Wunused -Wvla -fno-common -Wextra -Wmissing-prototypes -Wno-empty-body -Wno-missing-field-initializers -Wno-sign-compare -Wno-unused-parameter  -g -O2 -Wall -I. -DHAVE_SYSINFO -DGIT_HOST_CPU="\"x86_64\"" -DUSE_LIBPCRE2 -DHAVE_ALLOCA_H  -DUSE_CURL_FOR_IMAP_SEND -DSUPPORTS_SIMPLE_IPC -DSHA1_DC -DSHA1DC_NO_STANDARD_INCLUDES -DSHA1DC_INIT_SAFE_HASH_DEFAULT=0 -DSHA1DC_CUSTOM_INCLUDE_SHA1_C="\"cache.h\"" -DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="\"git-compat-util.h\"" -DSHA256_BLK  -DHAVE_PATHS_H -DHAVE_DEV_TTY -DHAVE_CLOCK_GETTIME -DHAVE_CLOCK_MONOTONIC -DHAVE_SYNC_FILE_RANGE -DHAVE_GETDELIM '-DPROCFS_EXECUTABLE_PATH="/proc/self/exe"' -DFREAD_READS_DIRECTORIES -DNO_STRLCPY -DSHELL_PATH='"/bin/sh"' -DPAGER_ENV='"LESS=FRX LV=-c"'  revision.c
    $ cc --version
    cc (Debian 10.3.0-11) 10.3.0
    Copyright (C) 2020 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


It would be quite sad if we had to allow decl-after-stmt, only to
allow

	stmt;
	for (type var = init; ...; ...) {
		...;
	}

because it should merely be a short-hand for

	stmt;
	{
	    type var;
	    for (var = init; ...; ...) {
		...;
	    }
	}

that does not need to allow decl-after-stmt.

Different compilers may behave differently, so it might be an issue
for somebody else, but I am hoping any reasonable compiler would
behave sensibly.

Thanks for raising a potential issue, as others can try it out in
their environment and see if their compilers behave well.
Phillip Wood Dec. 7, 2021, 11:10 a.m. UTC | #8
On 18/11/2021 07:09, Junio C Hamano wrote:
> Phillip Wood <phillip.wood123@gmail.com> writes:
> 
>> I like the idea of using a specific test balloon for the features that
>> we want to use but wont this one break the build for anyone doing
>> 'make DEVELOPER=1' because -Wdeclaration-after-statement will error
>> out.
> 
> I think you are missing '?' at the end of the sentence,

sorry yes I am

> but the
> answer is "no, at least not for me".
> 
>      # pardon my "make" wrapper; it is to pass DEVELOPER=1 etc. to
>      # the underlying "make" command.
>      $ Meta/Make V=1 revision.o
>      cc -o revision.o -c -MF ./.depend/revision.o.d -MQ revision.o -MMD -MP  -Werror -Wall -pedantic -Wpedantic -Wdeclaration-after-statement -Wformat-security -Wold-style-definition -Woverflow -Wpointer-arith -Wstrict-prototypes -Wunused -Wvla -fno-common -Wextra -Wmissing-prototypes -Wno-empty-body -Wno-missing-field-initializers -Wno-sign-compare -Wno-unused-parameter  -g -O2 -Wall -I. -DHAVE_SYSINFO -DGIT_HOST_CPU="\"x86_64\"" -DUSE_LIBPCRE2 -DHAVE_ALLOCA_H  -DUSE_CURL_FOR_IMAP_SEND -DSUPPORTS_SIMPLE_IPC -DSHA1_DC -DSHA1DC_NO_STANDARD_INCLUDES -DSHA1DC_INIT_SAFE_HASH_DEFAULT=0 -DSHA1DC_CUSTOM_INCLUDE_SHA1_C="\"cache.h\"" -DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="\"git-compat-util.h\"" -DSHA256_BLK  -DHAVE_PATHS_H -DHAVE_DEV_TTY -DHAVE_CLOCK_GETTIME -DHAVE_CLOCK_MONOTONIC -DHAVE_SYNC_FILE_RANGE -DHAVE_GETDELIM '-DPROCFS_EXECUTABLE_PATH="/proc/self/exe"' -DFREAD_READS_DIRECTORIES -DNO_STRLCPY -DSHELL_PATH='"/bin/sh"' -DPAGER_ENV='"LESS=FRX LV=-c"'  revision.c
>      $ cc --version
>      cc (Debian 10.3.0-11) 10.3.0
>      Copyright (C) 2020 Free Software Foundation, Inc.
>      This is free software; see the source for copying conditions.  There is NO
>      warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> 
> 
> It would be quite sad if we had to allow decl-after-stmt, only to
> allow
> 
> 	stmt;
> 	for (type var = init; ...; ...) {
> 		...;
> 	}
> 
> because it should merely be a short-hand for
> 
> 	stmt;
> 	{
> 	    type var;
> 	    for (var = init; ...; ...) {
> 		...;
> 	    }
> 	}
> 
> that does not need to allow decl-after-stmt.
> 
> Different compilers may behave differently, so it might be an issue
> for somebody else, but I am hoping any reasonable compiler would
> behave sensibly.
> 
> Thanks for raising a potential issue, as others can try it out in
> their environment and see if their compilers behave well.

Oh it seems I misunderstood exactly what decl-after-stmt does, thinking 
about it your explanation makes sense. I guess that means we have not 
had any warning flags set (because no such flags exist?)  to protect 
against the accidental introduction of the construct that this patch is 
testing compiler support for.

Best Wishes

Phillip
Junio C Hamano Dec. 7, 2021, 8:37 p.m. UTC | #9
Phillip Wood <phillip.wood123@gmail.com> writes:

> ... I guess that means we
> have not had any warning flags set (because no such flags exist?)  to
> protect against the accidental introduction of the construct that this
> patch is testing compiler support for.

I think we actually saw some instances of "for (type var = ..."
slipped through the review process, only to later get caught by
some other means.
Ævar Arnfjörð Bjarmason Dec. 8, 2021, 12:17 p.m. UTC | #10
On Wed, Nov 17 2021, Junio C Hamano wrote:

> Phillip Wood <phillip.wood123@gmail.com> writes:
>
>> I like the idea of using a specific test balloon for the features that
>> we want to use but wont this one break the build for anyone doing
>> 'make DEVELOPER=1' because -Wdeclaration-after-statement will error
>> out.
>
> I think you are missing '?' at the end of the sentence, but the
> answer is "no, at least not for me".
>
>     # pardon my "make" wrapper; it is to pass DEVELOPER=1 etc. to
>     # the underlying "make" command.
>     $ Meta/Make V=1 revision.o
>     cc -o revision.o -c -MF ./.depend/revision.o.d -MQ revision.o -MMD -MP  -Werror -Wall -pedantic -Wpedantic -Wdeclaration-after-statement -Wformat-security -Wold-style-definition -Woverflow -Wpointer-arith -Wstrict-prototypes -Wunused -Wvla -fno-common -Wextra -Wmissing-prototypes -Wno-empty-body -Wno-missing-field-initializers -Wno-sign-compare -Wno-unused-parameter  -g -O2 -Wall -I. -DHAVE_SYSINFO -DGIT_HOST_CPU="\"x86_64\"" -DUSE_LIBPCRE2 -DHAVE_ALLOCA_H  -DUSE_CURL_FOR_IMAP_SEND -DSUPPORTS_SIMPLE_IPC -DSHA1_DC -DSHA1DC_NO_STANDARD_INCLUDES -DSHA1DC_INIT_SAFE_HASH_DEFAULT=0 -DSHA1DC_CUSTOM_INCLUDE_SHA1_C="\"cache.h\"" -DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="\"git-compat-util.h\"" -DSHA256_BLK  -DHAVE_PATHS_H -DHAVE_DEV_TTY -DHAVE_CLOCK_GETTIME -DHAVE_CLOCK_MONOTONIC -DHAVE_SYNC_FILE_RANGE -DHAVE_GETDELIM '-DPROCFS_EXECUTABLE_PATH="/proc/self/exe"' -DFREAD_READS_DIRECTORIES -DNO_STRLCPY -DSHELL_PATH='"/bin/sh"' -DPAGER_ENV='"LESS=FRX LV=-c"'  revision.c
>     $ cc --version
>     cc (Debian 10.3.0-11) 10.3.0
>     Copyright (C) 2020 Free Software Foundation, Inc.
>     This is free software; see the source for copying conditions.  There is NO
>     warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
>
>
> It would be quite sad if we had to allow decl-after-stmt, only to
> allow
>
> 	stmt;
> 	for (type var = init; ...; ...) {
> 		...;
> 	}
>
> because it should merely be a short-hand for
>
> 	stmt;
> 	{
> 	    type var;
> 	    for (var = init; ...; ...) {
> 		...;
> 	    }
> 	}
>
> that does not need to allow decl-after-stmt.

Why would that be sad? The intent of -Wdeclaration-after-statement is to
catch C90 compatibility issues. Maybe we don't want to enable everything
C99-related in this area at once, but why shouldn't we be removing
-Wdeclaration-after-statement once we have a hard C99 dependency?

I usually prefer declaring variables up-front just as a metter of style,
and it usually encourages you to split up functions that are
unnecessarily long.

But I think being able to do it in some situations also helps
readability. E.g. I'm re-rolling my cat-file usage topic now and spotted
this nice candidate (which we'd error on now with CC=gcc and
DEVELOPER=1):
	
	diff --git a/builtin/cat-file.c b/builtin/cat-file.c
	index f5437c2d045..a43df23a7cd 100644
	--- a/builtin/cat-file.c
	+++ b/builtin/cat-file.c
	@@ -644,8 +644,6 @@ static int batch_option_callback(const struct option *opt,
	 int cmd_cat_file(int argc, const char **argv, const char *prefix)
	 {
	 	int opt = 0;
	-	int opt_cw = 0;
	-	int opt_epts = 0;
	 	const char *exp_type = NULL, *obj_name = NULL;
	 	struct batch_options batch = {0};
	 	int unknown_type = 0;
	@@ -708,8 +706,8 @@ int cmd_cat_file(int argc, const char **argv, const char *prefix)
	 	batch.buffer_output = -1;
	 
	 	argc = parse_options(argc, argv, prefix, options, usage, 0);
	-	opt_cw = (opt == 'c' || opt == 'w');
	-	opt_epts = (opt == 'e' || opt == 'p' || opt == 't' || opt == 's');
	+	const int opt_cw = (opt == 'c' || opt == 'w');
	+	const opt_epts = (opt == 'e' || opt == 'p' || opt == 't' || opt == 's');
	 
	 	/* --batch-all-objects? */
	 	if (opt == 'b')

I.e. in this case I'm declaring a variable merely as a short-hand for
accessing "opt", and due to the need for parse_options() we can't really
declare it in a way that's resonable before any statement in the
function.

By having -Wdeclaration-after-statement we're forced to make it
non-const, and having it "const" helps readability, you know as soon as
you see it that it won't be modified.

That particular example is certainly open to bikeshedding, but I think
the general point that it's not categorically bad holds, and therefore
if we don't need it for compiler compatibility it's probably a good idea
to allow it.
Junio C Hamano Dec. 8, 2021, 5:05 p.m. UTC | #11
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> Why would that be sad? The intent of -Wdeclaration-after-statement is to
> catch C90 compatibility issues. Maybe we don't want to enable everything
> C99-related in this area at once, but why shouldn't we be removing
> -Wdeclaration-after-statement once we have a hard C99 dependency?

We already heard from people that we do not want vla, and I agree
that we do not want all C99.  decl-after-stmt is something I
definitely do not want in our code, in order to keep the code more
readable by declaring the things that will be used in the scope
upfront, with documentation if needed.  It tends to encourage us to
keep our blocks smaller.
diff mbox series

Patch

diff --git a/revision.c b/revision.c
index 9dff845bed..44492f2c02 100644
--- a/revision.c
+++ b/revision.c
@@ -43,10 +43,8 @@  static inline int want_ancestry(const struct rev_info *revs);
 
 void show_object_with_name(FILE *out, struct object *obj, const char *name)
 {
-	const char *p;
-
 	fprintf(out, "%s ", oid_to_hex(&obj->oid));
-	for (p = name; *p && *p != '\n'; p++)
+	for (const char *p = name; *p && *p != '\n'; p++)
 		fputc(*p, out);
 	fputc('\n', out);
 }