* [PATCH 1/2] ctime.3: Use VLA notation for [as]ctime_r() buffer
@ 2021-10-20 20:22 Alejandro Colomar
2021-10-20 20:22 ` [PATCH 2/2] ctime.3, strftime.3, strptime.3, timegm.3: Add [[gnu::nonnull]] to <time.h> prototypes Alejandro Colomar
[not found] ` <20211021092746.78bc82f8@inria.fr>
0 siblings, 2 replies; 10+ messages in thread
From: Alejandro Colomar @ 2021-10-20 20:22 UTC (permalink / raw)
To: mtk.manpages; +Cc: Alejandro Colomar, linux-man, Jens Gustedt, Glibc
As N2417 (part of C2x) suggests. This syntax is very informative,
and also, if used by library implementers, can improve static analysis.
Since it is backwards compatible with pointer syntax, we can do this.
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Cc: Jens Gustedt <jens.gustedt@loria.fr>
Cc: Glibc <libc-alpha@sourceware.org>
---
man3/ctime.3 | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/man3/ctime.3 b/man3/ctime.3
index 0e2068a09..0620741e9 100644
--- a/man3/ctime.3
+++ b/man3/ctime.3
@@ -41,10 +41,12 @@ localtime_r \- transform date and time to broken-down time or ASCII
.B #include <time.h>
.PP
.BI "char *asctime(const struct tm *" tm );
-.BI "char *asctime_r(const struct tm *restrict " tm ", char *restrict " buf );
+.BI "char *asctime_r(const struct tm *restrict " tm ,
+.BI " char " buf "[static restrict 26]);"
.PP
.BI "char *ctime(const time_t *" timep );
-.BI "char *ctime_r(const time_t *restrict " timep ", char *restrict " buf );
+.BI "char *ctime_r(const time_t *restrict " timep ,
+.BI " char " buf "[static restrict 26]);"
.PP
.BI "struct tm *gmtime(const time_t *" timep );
.BI "struct tm *gmtime_r(const time_t *restrict " timep ,
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/2] ctime.3, strftime.3, strptime.3, timegm.3: Add [[gnu::nonnull]] to <time.h> prototypes
2021-10-20 20:22 [PATCH 1/2] ctime.3: Use VLA notation for [as]ctime_r() buffer Alejandro Colomar
@ 2021-10-20 20:22 ` Alejandro Colomar
2021-10-21 8:13 ` AW: " Walter Harms
[not found] ` <20211021092746.78bc82f8@inria.fr>
1 sibling, 1 reply; 10+ messages in thread
From: Alejandro Colomar @ 2021-10-20 20:22 UTC (permalink / raw)
To: mtk.manpages; +Cc: Alejandro Colomar, linux-man, Jens Gustedt, Glibc
C2X changes the prototypes of <time.h> functions that accept a
pointer that cannot be NULL, to use 'static', which clearly
denotes that passing NULL is Undefined Behavior.
For example, 'time_t mktime(struct tm tm[static 1]);'.
This change is backwards compatible, since array notation is just
syntactic sugar for pointers, and the Undefined Behavior in case
of a pointer already existed (in the wording); it just wasn't
clear from the prototype itself.
However, that forces the use of VLA (array) notation for something
that is *not* an array. It is cofusing, probably too much for
some programmers not so familiar with the difference between an
array and a pointer, and that happens more than we would like.
Even for programmers that clearly know the difference between an
array and a pointer, this is at least misleading.
That happens because the standard lacks a 'nonnull' attribute, and
only has that (VLA) way of expressing what GCC can express with
'[[gnu::nonnull]]' (a.k.a. '__attribute__((__nonnull__))').
Expressing that NULL pointers shall invoke Undefined Behavior in
the prototype of a function is *way* more readable than having to
read through the whole manual page text, so ideally we should also
follow the standard idea of expressing that. But we can make use
of more advanced techniques such as the GCC attribute, which help
keep the information that those pointers are actually pointers and
not arrays.
From the 2 different attribute notations, let's use the "C++" one,
which will be part of the standard in C2X (unlike __attribute__),
and is also shorter, which helps keep the SYNOPSIS short (mostly
one-liner prototypes).
See <http://www.open-std.org/JTC1/SC22/WG14/www/docs/n2417.pdf>
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Cc: Jens Gustedt <jens.gustedt@loria.fr>
Cc: Glibc <libc-alpha@sourceware.org>
---
man3/ctime.3 | 26 +++++++++++++-------------
man3/strftime.3 | 1 +
man3/strptime.3 | 1 +
man3/timegm.3 | 4 ++--
4 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/man3/ctime.3 b/man3/ctime.3
index 0620741e9..42021a588 100644
--- a/man3/ctime.3
+++ b/man3/ctime.3
@@ -40,23 +40,23 @@ localtime_r \- transform date and time to broken-down time or ASCII
.nf
.B #include <time.h>
.PP
-.BI "char *asctime(const struct tm *" tm );
-.BI "char *asctime_r(const struct tm *restrict " tm ,
-.BI " char " buf "[static restrict 26]);"
+.BI "[[gnu::nonnull]] char *asctime(const struct tm *" tm );
+.BI "[[gnu::nonnull]] char *asctime_r(const struct tm *restrict " tm ,
+.BI " char " buf "[static restrict 26]);"
.PP
-.BI "char *ctime(const time_t *" timep );
-.BI "char *ctime_r(const time_t *restrict " timep ,
-.BI " char " buf "[static restrict 26]);"
+.BI "[[gnu::nonnull]] char *ctime(const time_t *" timep );
+.BI "[[gnu::nonnull]] char *ctime_r(const time_t *restrict " timep ,
+.BI " char " buf "[static restrict 26]);"
.PP
-.BI "struct tm *gmtime(const time_t *" timep );
-.BI "struct tm *gmtime_r(const time_t *restrict " timep ,
-.BI " struct tm *restrict " result );
+.BI "[[gnu::nonnull]] struct tm *gmtime(const time_t *" timep );
+.BI "[[gnu::nonnull]] struct tm *gmtime_r(const time_t *restrict " timep ,
+.BI " struct tm *restrict " result );
.PP
-.BI "struct tm *localtime(const time_t *" timep );
-.BI "struct tm *localtime_r(const time_t *restrict " timep ,
-.BI " struct tm *restrict " result );
+.BI "[[gnu::nonnull]] struct tm *localtime(const time_t *" timep );
+.BI "[[gnu::nonnull]] struct tm *localtime_r(const time_t *restrict " timep ,
+.BI " struct tm *restrict " result );
.PP
-.BI "time_t mktime(struct tm *" tm );
+.BI "[[gnu::nonnull]] time_t mktime(struct tm *" tm );
.fi
.PP
.RS -4
diff --git a/man3/strftime.3 b/man3/strftime.3
index a24ea720b..715b30edb 100644
--- a/man3/strftime.3
+++ b/man3/strftime.3
@@ -41,6 +41,7 @@ strftime \- format date and time
.nf
.B #include <time.h>
.PP
+.B [[gnu::nonnull]]
.BI "size_t strftime(char *restrict " s ", size_t " max ,
.BI " const char *restrict " format ,
.BI " const struct tm *restrict " tm );
diff --git a/man3/strptime.3 b/man3/strptime.3
index d6595d4bf..c1b334d87 100644
--- a/man3/strptime.3
+++ b/man3/strptime.3
@@ -36,6 +36,7 @@ strptime \- convert a string representation of time to a time tm structure
.BR "#define _XOPEN_SOURCE" " /* See feature_test_macros(7) */"
.B #include <time.h>
.PP
+.B [[gnu::nonnull]]
.BI "char *strptime(const char *restrict " s ", const char *restrict " format ,
.BI " struct tm *restrict " tm );
.fi
diff --git a/man3/timegm.3 b/man3/timegm.3
index b848e83e1..18b6e4847 100644
--- a/man3/timegm.3
+++ b/man3/timegm.3
@@ -29,8 +29,8 @@ timegm, timelocal \- inverses of gmtime and localtime
.nf
.B #include <time.h>
.PP
-.BI "time_t timelocal(struct tm *" tm );
-.BI "time_t timegm(struct tm *" tm );
+.BI "[[gnu::nonnull]] time_t timelocal(struct tm *" tm );
+.BI "[[gnu::nonnull]] time_t timegm(struct tm *" tm );
.PP
.fi
.RS -4
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* AW: [PATCH 2/2] ctime.3, strftime.3, strptime.3, timegm.3: Add [[gnu::nonnull]] to <time.h> prototypes
2021-10-20 20:22 ` [PATCH 2/2] ctime.3, strftime.3, strptime.3, timegm.3: Add [[gnu::nonnull]] to <time.h> prototypes Alejandro Colomar
@ 2021-10-21 8:13 ` Walter Harms
2021-10-21 9:01 ` Alejandro Colomar (man-pages)
0 siblings, 1 reply; 10+ messages in thread
From: Walter Harms @ 2021-10-21 8:13 UTC (permalink / raw)
To: Alejandro Colomar, mtk.manpages@gmail.com
Cc: linux-man@vger.kernel.org, Jens Gustedt, Glibc
Hi thx,
for the information, i was not aware of changes for the time interface
and i do a lot of programming with them.
Since you ask for it:
I do not like the [[gnu::nonnull]] as shown below.
The position triggers the wrong assoziation for me.
Things in front of a function are used to describe a return values.
To be fair the array solution is not great either.
my idea would to add a comment like
char *asctime(const struct tm *" tm /* not null */);
What is happening inside time.h is something different.
If you thing the compiler should check for not null
he needs a hint.
IMHO it is the responsibility of the programmer
to make sure that the propper arguments are provided.
re,
wh
________________________________________
Von: Alejandro Colomar <alx.manpages@gmail.com>
Gesendet: Mittwoch, 20. Oktober 2021 22:22:41
An: mtk.manpages@gmail.com
Cc: Alejandro Colomar; linux-man@vger.kernel.org; Jens Gustedt; Glibc
Betreff: [PATCH 2/2] ctime.3, strftime.3, strptime.3, timegm.3: Add [[gnu::nonnull]] to <time.h> prototypes
WARNUNG: Diese E-Mail kam von außerhalb der Organisation. Klicken Sie nicht auf Links oder öffnen Sie keine Anhänge, es sei denn, Sie kennen den/die Absender*in und wissen, dass der Inhalt sicher ist.
C2X changes the prototypes of <time.h> functions that accept a
pointer that cannot be NULL, to use 'static', which clearly
denotes that passing NULL is Undefined Behavior.
For example, 'time_t mktime(struct tm tm[static 1]);'.
This change is backwards compatible, since array notation is just
syntactic sugar for pointers, and the Undefined Behavior in case
of a pointer already existed (in the wording); it just wasn't
clear from the prototype itself.
However, that forces the use of VLA (array) notation for something
that is *not* an array. It is cofusing, probably too much for
some programmers not so familiar with the difference between an
array and a pointer, and that happens more than we would like.
Even for programmers that clearly know the difference between an
array and a pointer, this is at least misleading.
That happens because the standard lacks a 'nonnull' attribute, and
only has that (VLA) way of expressing what GCC can express with
'[[gnu::nonnull]]' (a.k.a. '__attribute__((__nonnull__))').
Expressing that NULL pointers shall invoke Undefined Behavior in
the prototype of a function is *way* more readable than having to
read through the whole manual page text, so ideally we should also
follow the standard idea of expressing that. But we can make use
of more advanced techniques such as the GCC attribute, which help
keep the information that those pointers are actually pointers and
not arrays.
From the 2 different attribute notations, let's use the "C++" one,
which will be part of the standard in C2X (unlike __attribute__),
and is also shorter, which helps keep the SYNOPSIS short (mostly
one-liner prototypes).
See <http://www.open-std.org/JTC1/SC22/WG14/www/docs/n2417.pdf>
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
Cc: Jens Gustedt <jens.gustedt@loria.fr>
Cc: Glibc <libc-alpha@sourceware.org>
---
man3/ctime.3 | 26 +++++++++++++-------------
man3/strftime.3 | 1 +
man3/strptime.3 | 1 +
man3/timegm.3 | 4 ++--
4 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/man3/ctime.3 b/man3/ctime.3
index 0620741e9..42021a588 100644
--- a/man3/ctime.3
+++ b/man3/ctime.3
@@ -40,23 +40,23 @@ localtime_r \- transform date and time to broken-down time or ASCII
.nf
.B #include <time.h>
.PP
-.BI "char *asctime(const struct tm *" tm );
-.BI "char *asctime_r(const struct tm *restrict " tm ,
-.BI " char " buf "[static restrict 26]);"
+.BI "[[gnu::nonnull]] char *asctime(const struct tm *" tm );
+.BI "[[gnu::nonnull]] char *asctime_r(const struct tm *restrict " tm ,
+.BI " char " buf "[static restrict 26]);"
.PP
-.BI "char *ctime(const time_t *" timep );
-.BI "char *ctime_r(const time_t *restrict " timep ,
-.BI " char " buf "[static restrict 26]);"
+.BI "[[gnu::nonnull]] char *ctime(const time_t *" timep );
+.BI "[[gnu::nonnull]] char *ctime_r(const time_t *restrict " timep ,
+.BI " char " buf "[static restrict 26]);"
.PP
-.BI "struct tm *gmtime(const time_t *" timep );
-.BI "struct tm *gmtime_r(const time_t *restrict " timep ,
-.BI " struct tm *restrict " result );
+.BI "[[gnu::nonnull]] struct tm *gmtime(const time_t *" timep );
+.BI "[[gnu::nonnull]] struct tm *gmtime_r(const time_t *restrict " timep ,
+.BI " struct tm *restrict " result );
.PP
-.BI "struct tm *localtime(const time_t *" timep );
-.BI "struct tm *localtime_r(const time_t *restrict " timep ,
-.BI " struct tm *restrict " result );
+.BI "[[gnu::nonnull]] struct tm *localtime(const time_t *" timep );
+.BI "[[gnu::nonnull]] struct tm *localtime_r(const time_t *restrict " timep ,
+.BI " struct tm *restrict " result );
.PP
-.BI "time_t mktime(struct tm *" tm );
+.BI "[[gnu::nonnull]] time_t mktime(struct tm *" tm );
.fi
.PP
.RS -4
diff --git a/man3/strftime.3 b/man3/strftime.3
index a24ea720b..715b30edb 100644
--- a/man3/strftime.3
+++ b/man3/strftime.3
@@ -41,6 +41,7 @@ strftime \- format date and time
.nf
.B #include <time.h>
.PP
+.B [[gnu::nonnull]]
.BI "size_t strftime(char *restrict " s ", size_t " max ,
.BI " const char *restrict " format ,
.BI " const struct tm *restrict " tm );
diff --git a/man3/strptime.3 b/man3/strptime.3
index d6595d4bf..c1b334d87 100644
--- a/man3/strptime.3
+++ b/man3/strptime.3
@@ -36,6 +36,7 @@ strptime \- convert a string representation of time to a time tm structure
.BR "#define _XOPEN_SOURCE" " /* See feature_test_macros(7) */"
.B #include <time.h>
.PP
+.B [[gnu::nonnull]]
.BI "char *strptime(const char *restrict " s ", const char *restrict " format ,
.BI " struct tm *restrict " tm );
.fi
diff --git a/man3/timegm.3 b/man3/timegm.3
index b848e83e1..18b6e4847 100644
--- a/man3/timegm.3
+++ b/man3/timegm.3
@@ -29,8 +29,8 @@ timegm, timelocal \- inverses of gmtime and localtime
.nf
.B #include <time.h>
.PP
-.BI "time_t timelocal(struct tm *" tm );
-.BI "time_t timegm(struct tm *" tm );
+.BI "[[gnu::nonnull]] time_t timelocal(struct tm *" tm );
+.BI "[[gnu::nonnull]] time_t timegm(struct tm *" tm );
.PP
.fi
.RS -4
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: AW: [PATCH 2/2] ctime.3, strftime.3, strptime.3, timegm.3: Add [[gnu::nonnull]] to <time.h> prototypes
2021-10-21 8:13 ` AW: " Walter Harms
@ 2021-10-21 9:01 ` Alejandro Colomar (man-pages)
2021-10-21 17:40 ` Paul Eggert
0 siblings, 1 reply; 10+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-10-21 9:01 UTC (permalink / raw)
To: Walter Harms, Jens Gustedt
Cc: mtk.manpages@gmail.com, linux-man@vger.kernel.org, Glibc
Hey Walter! and Jens!
On 10/21/21 10:13 AM, Walter Harms wrote:
> Hi thx,
> for the information, i was not aware of changes for the time interface
> and i do a lot of programming with them.
Apparently, those changes finally did not make it into the standard (as
Jens pointed out to me). The reason was C++-compatibility.
>
>
> Since you ask for it:
> I do not like the [[gnu::nonnull]] as shown below.
> The position triggers the wrong assoziation for me.
> Things in front of a function are used to describe a return values.
I just checked the valid syntax accepted by the standard:
[
6.7 Declarations
[...]
Semantics
[...]
9 Except where specified otherwise, the meaning of an attribute
declaration is implementation-defined.
10 EXAMPLE In the declaration for an entity, attributes appertaining to
that entity may appear at the start of the declarationand after the
identifier for that declaration.
[[deprecated]] void f [[deprecated]] (void); // valid
Forward references: declarators (6.7.6), enumeration specifiers
(6.7.2.2), initialization (6.7.9), typenames (6.7.7), type qualifiers
(6.7.3).
]
So we could put it in any of those 2 positions. Is there any reason
that one is better (more readable / less ambiguous) than the other? We
should decide very carefully which one to use.
BTW, this example reminds me of the deprecated functions, for which I'm
going to add [[deprecated]] to clearly mark those. That's something
that had been itching me for a long time :).
>
> To be fair the array solution is not great either.
>
> my idea would to add a comment like
> char *asctime(const struct tm *" tm /* not null */);
I think the C language is more universal than comments. If we can use
standard features of the language (or even GNU extensions, like in this
case), that will be readable across anyone that understands C or GNU C.
Comments are very personal, and do not have a universal meaning, and
that's why I try to avoid them in the man-pages SYNOPSIS as much as I
can. Apart from that, a comment after each parameter would be much more
noisy than a single [[gnu::nonnull]].
>
> What is happening inside time.h is something different.
I guess you mean in the implementation side, right? time/mktime.c for
example.
>
> If you thing the compiler should check for not null
> he needs a hint.
>
> IMHO it is the responsibility of the programmer
> to make sure that the propper arguments are provided.
Sure, and that's exactly the reason to add these attributes to the
prototype. To tell the programmer that NULL is *not* a proper argument.
I don't consider these attributes as optimization opportunities for
the compiler (which they are, BTW), but mainly as documentation for the
user of the API. Since the man-pages are one of the most used
documentation sources for C functions, I think documenting these
attributes makes a lot of sense.
But yes, we should think very carefully the position in which we should
put them; especially since many programmers will not read the standard,
and instead just imitate what they see in the manual pages, so we better
use the least ambiguous syntax possible.
Jens, since IIRC it was you who added attributes to C2X, could you
please help us deciding between the two options?
Thanks!
Alex
>
> re,
> wh
>
> ________________________________________
> Von: Alejandro Colomar <alx.manpages@gmail.com>
> Gesendet: Mittwoch, 20. Oktober 2021 22:22:41
> An: mtk.manpages@gmail.com
> Cc: Alejandro Colomar; linux-man@vger.kernel.org; Jens Gustedt; Glibc
> Betreff: [PATCH 2/2] ctime.3, strftime.3, strptime.3, timegm.3: Add [[gnu::nonnull]] to <time.h> prototypes
>
> WARNUNG: Diese E-Mail kam von außerhalb der Organisation. Klicken Sie nicht auf Links oder öffnen Sie keine Anhänge, es sei denn, Sie kennen den/die Absender*in und wissen, dass der Inhalt sicher ist.
>
>
> C2X changes the prototypes of <time.h> functions that accept a
> pointer that cannot be NULL, to use 'static', which clearly
> denotes that passing NULL is Undefined Behavior.
>
> For example, 'time_t mktime(struct tm tm[static 1]);'.
>
> This change is backwards compatible, since array notation is just
> syntactic sugar for pointers, and the Undefined Behavior in case
> of a pointer already existed (in the wording); it just wasn't
> clear from the prototype itself.
>
> However, that forces the use of VLA (array) notation for something
> that is *not* an array. It is cofusing, probably too much for
> some programmers not so familiar with the difference between an
> array and a pointer, and that happens more than we would like.
> Even for programmers that clearly know the difference between an
> array and a pointer, this is at least misleading.
>
> That happens because the standard lacks a 'nonnull' attribute, and
> only has that (VLA) way of expressing what GCC can express with
> '[[gnu::nonnull]]' (a.k.a. '__attribute__((__nonnull__))').
>
> Expressing that NULL pointers shall invoke Undefined Behavior in
> the prototype of a function is *way* more readable than having to
> read through the whole manual page text, so ideally we should also
> follow the standard idea of expressing that. But we can make use
> of more advanced techniques such as the GCC attribute, which help
> keep the information that those pointers are actually pointers and
> not arrays.
>
> From the 2 different attribute notations, let's use the "C++" one,
> which will be part of the standard in C2X (unlike __attribute__),
> and is also shorter, which helps keep the SYNOPSIS short (mostly
> one-liner prototypes).
>
> See <http://www.open-std.org/JTC1/SC22/WG14/www/docs/n2417.pdf>
>
> Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
> Cc: Jens Gustedt <jens.gustedt@loria.fr>
> Cc: Glibc <libc-alpha@sourceware.org>
> ---
> man3/ctime.3 | 26 +++++++++++++-------------
> man3/strftime.3 | 1 +
> man3/strptime.3 | 1 +
> man3/timegm.3 | 4 ++--
> 4 files changed, 17 insertions(+), 15 deletions(-)
>
> diff --git a/man3/ctime.3 b/man3/ctime.3
> index 0620741e9..42021a588 100644
> --- a/man3/ctime.3
> +++ b/man3/ctime.3
> @@ -40,23 +40,23 @@ localtime_r \- transform date and time to broken-down time or ASCII
> .nf
> .B #include <time.h>
> .PP
> -.BI "char *asctime(const struct tm *" tm );
> -.BI "char *asctime_r(const struct tm *restrict " tm ,
> -.BI " char " buf "[static restrict 26]);"
> +.BI "[[gnu::nonnull]] char *asctime(const struct tm *" tm );
> +.BI "[[gnu::nonnull]] char *asctime_r(const struct tm *restrict " tm ,
> +.BI " char " buf "[static restrict 26]);"
> .PP
> -.BI "char *ctime(const time_t *" timep );
> -.BI "char *ctime_r(const time_t *restrict " timep ,
> -.BI " char " buf "[static restrict 26]);"
> +.BI "[[gnu::nonnull]] char *ctime(const time_t *" timep );
> +.BI "[[gnu::nonnull]] char *ctime_r(const time_t *restrict " timep ,
> +.BI " char " buf "[static restrict 26]);"
> .PP
> -.BI "struct tm *gmtime(const time_t *" timep );
> -.BI "struct tm *gmtime_r(const time_t *restrict " timep ,
> -.BI " struct tm *restrict " result );
> +.BI "[[gnu::nonnull]] struct tm *gmtime(const time_t *" timep );
> +.BI "[[gnu::nonnull]] struct tm *gmtime_r(const time_t *restrict " timep ,
> +.BI " struct tm *restrict " result );
> .PP
> -.BI "struct tm *localtime(const time_t *" timep );
> -.BI "struct tm *localtime_r(const time_t *restrict " timep ,
> -.BI " struct tm *restrict " result );
> +.BI "[[gnu::nonnull]] struct tm *localtime(const time_t *" timep );
> +.BI "[[gnu::nonnull]] struct tm *localtime_r(const time_t *restrict " timep ,
> +.BI " struct tm *restrict " result );
> .PP
> -.BI "time_t mktime(struct tm *" tm );
> +.BI "[[gnu::nonnull]] time_t mktime(struct tm *" tm );
> .fi
> .PP
> .RS -4
> diff --git a/man3/strftime.3 b/man3/strftime.3
> index a24ea720b..715b30edb 100644
> --- a/man3/strftime.3
> +++ b/man3/strftime.3
> @@ -41,6 +41,7 @@ strftime \- format date and time
> .nf
> .B #include <time.h>
> .PP
> +.B [[gnu::nonnull]]
> .BI "size_t strftime(char *restrict " s ", size_t " max ,
> .BI " const char *restrict " format ,
> .BI " const struct tm *restrict " tm );
> diff --git a/man3/strptime.3 b/man3/strptime.3
> index d6595d4bf..c1b334d87 100644
> --- a/man3/strptime.3
> +++ b/man3/strptime.3
> @@ -36,6 +36,7 @@ strptime \- convert a string representation of time to a time tm structure
> .BR "#define _XOPEN_SOURCE" " /* See feature_test_macros(7) */"
> .B #include <time.h>
> .PP
> +.B [[gnu::nonnull]]
> .BI "char *strptime(const char *restrict " s ", const char *restrict " format ,
> .BI " struct tm *restrict " tm );
> .fi
> diff --git a/man3/timegm.3 b/man3/timegm.3
> index b848e83e1..18b6e4847 100644
> --- a/man3/timegm.3
> +++ b/man3/timegm.3
> @@ -29,8 +29,8 @@ timegm, timelocal \- inverses of gmtime and localtime
> .nf
> .B #include <time.h>
> .PP
> -.BI "time_t timelocal(struct tm *" tm );
> -.BI "time_t timegm(struct tm *" tm );
> +.BI "[[gnu::nonnull]] time_t timelocal(struct tm *" tm );
> +.BI "[[gnu::nonnull]] time_t timegm(struct tm *" tm );
> .PP
> .fi
> .RS -4
> --
> 2.33.0
>
--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] ctime.3: Use VLA notation for [as]ctime_r() buffer
[not found] ` <20211021092746.78bc82f8@inria.fr>
@ 2021-10-21 9:12 ` Alejandro Colomar (man-pages)
[not found] ` <20c1e58b-ba2b-f9df-ab1f-f80725414cf5@gmail.com>
1 sibling, 0 replies; 10+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-10-21 9:12 UTC (permalink / raw)
To: Jₑₙₛ Gustedt; +Cc: linux-man
Just forwarding a conversation to the list
On 10/21/21 9:27 AM, Jₑₙₛ Gustedt wrote:
> Hello Alejandro,
>
> On Wed, 20 Oct 2021 22:22:40 +0200, Alejandro Colomar wrote:
>
>> As N2417 (part of C2x) suggests. This syntax is very informative,
>> and also, if used by library implementers, can improve static
>> analysis.
>>
>> Since it is backwards compatible with pointer syntax, we can do this.
>
> I understand the intent, but these `_r` interfaces finally went into
> the standard without array notation. AFAIR one of the arguments was
> that the headers should be usable from C++.
>
> So I am not sure if it is consensus to have the documentation have a
> different form of the interfaces than the standard(s). I don't know if
> you'd also add the attributes that glibc uses to the `printf`
> interfaces, for example.
>
> I am not saying that you shouldn't, in the contrary it is probably a
> good idea to list all those semantic restrictions in the documented
> interface for which me have syntax. I just want to make sure that
> adding such semantic hints to the documentation is consensus and
> sufficiently well discussed.
>
> Thanks
> Jₑₙₛ
>
>
--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] ctime.3: Use VLA notation for [as]ctime_r() buffer
[not found] ` <20c1e58b-ba2b-f9df-ab1f-f80725414cf5@gmail.com>
@ 2021-10-21 9:13 ` Alejandro Colomar (man-pages)
[not found] ` <5782a3ea-9774-3acb-e365-1e4d03ed3358@gmail.com>
1 sibling, 0 replies; 10+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-10-21 9:13 UTC (permalink / raw)
To: Jₑₙₛ Gustedt, linux-man
Just forwarding a conversation to the list
On 10/21/21 10:17 AM, Alejandro Colomar (man-pages) wrote:
> Hello Jens,
>
> On 10/21/21 9:27 AM, Jₑₙₛ Gustedt wrote:
>> Hello Alejandro,
>>
>> On Wed, 20 Oct 2021 22:22:40 +0200, Alejandro Colomar wrote:
>>
>>> As N2417 (part of C2x) suggests. This syntax is very informative,
>>> and also, if used by library implementers, can improve static
>>> analysis.
>>>
>>> Since it is backwards compatible with pointer syntax, we can do this.
>>
>> I understand the intent, but these `_r` interfaces finally went into
>> the standard without array notation. AFAIR one of the arguments was
>> that the headers should be usable from C++.
>
> Hmm, I understand. If I may digress, that C/C++ incompatibility has
> been the only real pain in reusing my C headers in C++; so much that I
> have separate .h and .hxx header files for the same functions.
> Eventhough C++ with VLAs would be a bad idea, parameter VLAs are not
> really VLAs (in the sense of the same stack problems that alloca() has),
> but syntactic sugar for pointers. Would it be too much to ask to get
> C++ accept that C feature? Has it been discussed and is there any
> consensus that it should not be done? Or is it worth proposing to the
> C++ comitee?
>
>
>>
>> So I am not sure if it is consensus to have the documentation have a
>> different form of the interfaces than the standard(s). I don't know if
>> you'd also add the attributes that glibc uses to the `printf`
>> interfaces, for example. >
>> I am not saying that you shouldn't, in the contrary it is probably a
>> good idea to list all those semantic restrictions in the documented
>> interface for which me have syntax. I just want to make sure that
>> adding such semantic hints to the documentation is consensus and
>> sufficiently well discussed.
>
> We recently (a few months ago) added 'noreturn' and 'restrict' to the
> man-pages prototypes.
>
> My opinion is that we should only add a specific syntax if it adds very
> useful information that cannot easily be read from the rest of the
> prototype.
>
> noreturn and restrict are examples of that, and I think [static 26] in
> the case of these _r functions also are. Or also [[gnu::nonnull]],
> which BTW, as N2417 shows implicitly by the use of [static 1], which as
> I said in patch 2/2 is confusing, I would like to suggest for the
> standard to take it as [[nonnull]], probably for C3X I guess.
>
> However, some attributes are not that useful. I think
> [[gnu::fornat(printf, 3, 4)]] wouldn't add much valuable information to
> snprintf that isn't already readable from the prototype. It is an
> attribute only useful for the compiler/static analyzer, but not very
> much for the human (compared to the noise it adds).
>
> What I fear when adding these things is adding too much noise to the
> SYNOPSIS.
>
> Ideally, the standard and the man-pages would have the same prototypes.
> However, since the standard is not (and cannot be) perfect, when it
> has some limitations that it cannot overcome which we can, I'll be happy
> to differ from it. nonnull IMO is very useful in the SYNOPSIS, so I'd
> like to have it (and I'd also like the standard to have it, but that's
> likely to take a decade, if it happens at all). Also, the man-pages
> already use array notation in some specific cases (see pipe(2)), and
> they are mostly targeted at C programmers, so I think we can safely
> assume that a C++ reader will know the limitation of its language, and
> be able to translate C to C++ easily. If any glibc programmer has any
> concerns regarding that, this is the moment for giving a different
> opinion :).
>
> Thanks for your feedback!
>
> Alex
>
>
--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] ctime.3: Use VLA notation for [as]ctime_r() buffer
[not found] ` <5782a3ea-9774-3acb-e365-1e4d03ed3358@gmail.com>
@ 2021-10-21 9:14 ` Alejandro Colomar (man-pages)
[not found] ` <20211021110311.52541d69@inria.fr>
1 sibling, 0 replies; 10+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-10-21 9:14 UTC (permalink / raw)
To: Jₑₙₛ Gustedt, linux-man
Just forwarding a conversation to the list
On 10/21/21 10:27 AM, Alejandro Colomar (man-pages) wrote:
> Hi Jens,
>
> On 10/21/21 10:17 AM, Alejandro Colomar (man-pages) wrote:
>> Ideally, the standard and the man-pages would have the same
>> prototypes. However, since the standard is not (and cannot be)
>> perfect, when it has some limitations that it cannot overcome which we
>> can, I'll be happy to differ from it. nonnull IMO is very useful in
>> the SYNOPSIS, so I'd like to have it (and I'd also like the standard
>> to have it, but that's likely to take a decade, if it happens at
>> all). Also, the man-pages already use array notation in some specific
>> cases (see pipe(2)), and they are mostly targeted at C programmers, so
>> I think we can safely assume that a C++ reader will know the
>> limitation of its language, and be able to translate C to C++ easily.
>> If any glibc programmer has any concerns regarding that, this is the
>> moment for giving a different opinion :).
>
> I rethinked it a bit after seeing pipe(2) again. I never understood why
> 'static' should be needed at all in an array parameter. The standard
> could have also accepted [26] as requiring at least 26 elements in the
> array, without requiring the use of static. There may be reasons for
> that that I ignore, of course; maybe backwards compatibility.... But
> since the man-pages can present the same information without the static
> keyword, I'll edit my patches to just use [restrict 26], instead of
> [static restrict 26], which is more compact.
>
> BTW, I just noticed that these emails were offlist. If you want to keep
> them offlist, I'l do so, but we typically CC the list to have open
> discussions. If you give me permission, I'll forward these emails to
> the mailing lists.
>
> Cheers,
>
> Alex
>
--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] ctime.3: Use VLA notation for [as]ctime_r() buffer
[not found] ` <ec620c5e-0952-fe16-353c-0210d3bea6e8@gmail.com>
@ 2021-10-21 9:27 ` Alejandro Colomar (man-pages)
0 siblings, 0 replies; 10+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-10-21 9:27 UTC (permalink / raw)
To: Jₑₙₛ Gustedt, linux-man
Just forwarding a conversation to the list
On 10/21/21 11:20 AM, Alejandro Colomar (man-pages) wrote:
> Hello Jens,
>
> On 10/21/21 11:03 AM, Jₑₙₛ Gustedt wrote:
>> Hello Alejandro,
>>
>> On Thu, 21 Oct 2021 10:27:48 +0200, Alejandro Colomar (man-pages) wrote:
>>
>>> I rethinked it a bit after seeing pipe(2) again. I never understood
>>> why 'static' should be needed at all in an array parameter. The
>>> standard could have also accepted [26] as requiring at least 26
>>> elements in the array, without requiring the use of static.
>>
>> That's just speculation. They didn't, so for the compiler the
>> expression can just be ignore.
>
> Since static is not required to give a diagnostic, I don't see a real
> difference. Both can be ignored. But yes, that's speculating, and
> maybe I should probably propose to the committee having the same
> requirements for [26] as for [static 26] for C3X, and see what they come
> up with.
>
>> With what we have `static` conveys the
>> intent, and we should stick to that, I think.
>
> Yes, maybe sticking to the standard will be better.
>
>>
>>> There
>>> may be reasons for that that I ignore, of course; maybe backwards
>>> compatibility.... But since the man-pages can present the same
>>> information without the static keyword, I'll edit my patches to just
>>> use [restrict 26], instead of [static restrict 26], which is more
>>> compact.
>>
>> For the man pages that may be ok, but I still prefer that the headers
>> in the man page convey exactly the same normative information as the
>> specification of the standard.
>
> Okay. That makes sense.
>
>>
>>> BTW, I just noticed that these emails were offlist. If you want to
>>> keep them offlist, I'l do so, but we typically CC the list to have
>>> open discussions. If you give me permission, I'll forward these
>>> emails to the mailing lists.
>>
>> Do as you feel, no problem with me. I just didn't want to "fall in
>> your back" on a public list for which I don't have an idea of their
>> actual dialogue culture.
>
> Thanks!
> It's a small list with 2 maintainers and just a handful of other typical
> contributors. Typically, very nice compared to other lists, IMHO :)
>
> And BTW, thanks also for your many StackOverflow contributions! They
> have been very helpful to me :-)
>
>>
>> Thanks
>> Jₑₙₛ
>>
>>
>
>
--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: AW: [PATCH 2/2] ctime.3, strftime.3, strptime.3, timegm.3: Add [[gnu::nonnull]] to <time.h> prototypes
2021-10-21 9:01 ` Alejandro Colomar (man-pages)
@ 2021-10-21 17:40 ` Paul Eggert
2021-10-21 20:54 ` Alejandro Colomar (man-pages)
0 siblings, 1 reply; 10+ messages in thread
From: Paul Eggert @ 2021-10-21 17:40 UTC (permalink / raw)
To: Alejandro Colomar (man-pages), Walter Harms, Jens Gustedt
Cc: linux-man@vger.kernel.org, Glibc, mtk.manpages@gmail.com
On 10/21/21 02:01, Alejandro Colomar (man-pages) via Libc-alpha wrote:
> 10 EXAMPLE In the declaration for an entity, attributes appertaining
> to that entity may appear at the start of the declarationand after the
> identifier for that declaration.
>
> [[deprecated]] void f [[deprecated]] (void); // valid
>
> Forward references: declarators (6.7.6), enumeration specifiers
> (6.7.2.2), initialization (6.7.9), typenames (6.7.7), type qualifiers
> (6.7.3).
> ]
>
> So we could put it in any of those 2 positions. Is there any reason
> that one is better (more readable / less ambiguous) than the other? We
> should decide very carefully which one to use.
"f (...)" is hardwired into people's brains for function calls, and we
shouldn't put anything between the "f" and the "(" to confuse this
longstanding syntactic pattern. So this stuff should go at the start of
the declaration, not after the identifier.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: AW: [PATCH 2/2] ctime.3, strftime.3, strptime.3, timegm.3: Add [[gnu::nonnull]] to <time.h> prototypes
2021-10-21 17:40 ` Paul Eggert
@ 2021-10-21 20:54 ` Alejandro Colomar (man-pages)
0 siblings, 0 replies; 10+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-10-21 20:54 UTC (permalink / raw)
To: Paul Eggert, Walter Harms, Jens Gustedt
Cc: linux-man@vger.kernel.org, Glibc, mtk.manpages@gmail.com
On 10/21/21 7:40 PM, Paul Eggert wrote:
> "f (...)" is hardwired into people's brains for function calls, and we
> shouldn't put anything between the "f" and the "(" to confuse this
> longstanding syntactic pattern. So this stuff should go at the start of
> the declaration, not after the identifier.
Yup.
Thanks,
Alex
--
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-10-21 20:54 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-10-20 20:22 [PATCH 1/2] ctime.3: Use VLA notation for [as]ctime_r() buffer Alejandro Colomar
2021-10-20 20:22 ` [PATCH 2/2] ctime.3, strftime.3, strptime.3, timegm.3: Add [[gnu::nonnull]] to <time.h> prototypes Alejandro Colomar
2021-10-21 8:13 ` AW: " Walter Harms
2021-10-21 9:01 ` Alejandro Colomar (man-pages)
2021-10-21 17:40 ` Paul Eggert
2021-10-21 20:54 ` Alejandro Colomar (man-pages)
[not found] ` <20211021092746.78bc82f8@inria.fr>
2021-10-21 9:12 ` [PATCH 1/2] ctime.3: Use VLA notation for [as]ctime_r() buffer Alejandro Colomar (man-pages)
[not found] ` <20c1e58b-ba2b-f9df-ab1f-f80725414cf5@gmail.com>
2021-10-21 9:13 ` Alejandro Colomar (man-pages)
[not found] ` <5782a3ea-9774-3acb-e365-1e4d03ed3358@gmail.com>
2021-10-21 9:14 ` Alejandro Colomar (man-pages)
[not found] ` <20211021110311.52541d69@inria.fr>
[not found] ` <ec620c5e-0952-fe16-353c-0210d3bea6e8@gmail.com>
2021-10-21 9:27 ` Alejandro Colomar (man-pages)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox