Merge branch 'ab/coding-guidelines-c99'
Update CodingGuidelines to clarify what features to use and avoid in C99. * ab/coding-guidelines-c99: CodingGuidelines: recommend against unportable C99 struct syntax CodingGuidelines: mention C99 features we can't use CodingGuidelines: allow declaring variables in for loops CodingGuidelines: mention dynamic C99 initializer elements CodingGuidelines: update for C99
This commit is contained in:
commit
179eb1d967
@ -202,10 +202,19 @@ For C programs:
|
|||||||
by e.g. "echo DEVELOPER=1 >>config.mak".
|
by e.g. "echo DEVELOPER=1 >>config.mak".
|
||||||
|
|
||||||
- We try to support a wide range of C compilers to compile Git with,
|
- We try to support a wide range of C compilers to compile Git with,
|
||||||
including old ones. You should not use features from newer C
|
including old ones. As of Git v2.35.0 Git requires C99 (we check
|
||||||
|
"__STDC_VERSION__"). You should not use features from a newer C
|
||||||
standard, even if your compiler groks them.
|
standard, even if your compiler groks them.
|
||||||
|
|
||||||
There are a few exceptions to this guideline:
|
New C99 features have been phased in gradually, if something's new
|
||||||
|
in C99 but not used yet don't assume that it's safe to use, some
|
||||||
|
compilers we target have only partial support for it. These are
|
||||||
|
considered safe to use:
|
||||||
|
|
||||||
|
. since around 2007 with 2b6854c863a, we have been using
|
||||||
|
initializer elements which are not computable at load time. E.g.:
|
||||||
|
|
||||||
|
const char *args[] = {"constant", variable, NULL};
|
||||||
|
|
||||||
. since early 2012 with e1327023ea, we have been using an enum
|
. since early 2012 with e1327023ea, we have been using an enum
|
||||||
definition whose last element is followed by a comma. This, like
|
definition whose last element is followed by a comma. This, like
|
||||||
@ -221,18 +230,24 @@ For C programs:
|
|||||||
. since early 2021 with 765dc168882, we have been using variadic
|
. since early 2021 with 765dc168882, we have been using variadic
|
||||||
macros, mostly for printf-like trace and debug macros.
|
macros, mostly for printf-like trace and debug macros.
|
||||||
|
|
||||||
These used to be forbidden, but we have not heard any breakage
|
. since late 2021 with 44ba10d6, we have had variables declared in
|
||||||
report, and they are assumed to be safe.
|
the for loop "for (int i = 0; i < 10; i++)".
|
||||||
|
|
||||||
|
New C99 features that we cannot use yet:
|
||||||
|
|
||||||
|
. %z and %zu as a printf() argument for a size_t (the %z being for
|
||||||
|
the POSIX-specific ssize_t). Instead you should use
|
||||||
|
printf("%"PRIuMAX, (uintmax_t)v). These days the MSVC version we
|
||||||
|
rely on supports %z, but the C library used by MinGW does not.
|
||||||
|
|
||||||
|
. Shorthand like ".a.b = *c" in struct initializations is known to
|
||||||
|
trip up an older IBM XLC version, use ".a = { .b = *c }" instead.
|
||||||
|
See the 33665d98 (reftable: make assignments portable to AIX xlc
|
||||||
|
v12.01, 2022-03-28).
|
||||||
|
|
||||||
- Variables have to be declared at the beginning of the block, before
|
- Variables have to be declared at the beginning of the block, before
|
||||||
the first statement (i.e. -Wdeclaration-after-statement).
|
the first statement (i.e. -Wdeclaration-after-statement).
|
||||||
|
|
||||||
- Declaring a variable in the for loop "for (int i = 0; i < 10; i++)"
|
|
||||||
is still not allowed in this codebase. We are in the process of
|
|
||||||
allowing it by waiting to see that 44ba10d6 (revision: use C99
|
|
||||||
declaration of variable in for() loop, 2021-11-14) does not get
|
|
||||||
complaints. Let's revisit this around November 2022.
|
|
||||||
|
|
||||||
- NULL pointers shall be written as NULL, not as 0.
|
- NULL pointers shall be written as NULL, not as 0.
|
||||||
|
|
||||||
- When declaring pointers, the star sides with the variable
|
- When declaring pointers, the star sides with the variable
|
||||||
|
@ -47,13 +47,6 @@ static inline int want_ancestry(const struct rev_info *revs);
|
|||||||
void show_object_with_name(FILE *out, struct object *obj, const char *name)
|
void show_object_with_name(FILE *out, struct object *obj, const char *name)
|
||||||
{
|
{
|
||||||
fprintf(out, "%s ", oid_to_hex(&obj->oid));
|
fprintf(out, "%s ", oid_to_hex(&obj->oid));
|
||||||
/*
|
|
||||||
* 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. In the meantime,
|
|
||||||
* adding -std=gnu99 to CFLAGS may help if you are with older GCC.
|
|
||||||
*/
|
|
||||||
for (const char *p = name; *p && *p != '\n'; p++)
|
for (const char *p = name; *p && *p != '\n'; p++)
|
||||||
fputc(*p, out);
|
fputc(*p, out);
|
||||||
fputc('\n', out);
|
fputc('\n', out);
|
||||||
|
Loading…
Reference in New Issue
Block a user