summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlejandro Colomar <alx.manpages@gmail.com>2021-11-15 16:47:54 +0100
committerAlejandro Colomar <alx.manpages@gmail.com>2021-11-15 16:47:54 +0100
commit383870120327f93fcbe1a9bdafb39d5103ace9ee (patch)
tree5e61f13241274268288a7fcd74df84b43bf87dd9
nonnull.7: Initial draft
Signed-off-by: Alejandro Colomar <alx.manpages@gmail.com>
-rw-r--r--nonnull.7228
1 files changed, 228 insertions, 0 deletions
diff --git a/nonnull.7 b/nonnull.7
new file mode 100644
index 0000000..1ba0218
--- /dev/null
+++ b/nonnull.7
@@ -0,0 +1,228 @@
+.TH nonnull 3 2021-11-15 C3X Nxxxx
+.SH NAME
+nonnull \- non-null pointer
+.SH SYNOPSIS
+.nf
+.I type-qualifier:
+.B " const"
+.B " nonnull"
+.B " restrict"
+.B " volatile"
+.B " _Atomic"
+.fi
+.SH DESCRIPTION
+.SS Constraints
+Types other than pointer types
+shall not be
+.BR \%nonnull -qualified.
+.SS Semantics
+The properties associated with qualified types are meaningfull
+only for expressions that are lvalues.
+.PP
+If the same qualifier appears more than once
+in the same specifier-qualifier list
+or as declaration specifiers,
+either directly or via one or more
+.BR typedef s,
+the behavior is the same as if it appeared only once.
+If other qualifiers appear along with the
+.B \%_Atomic
+qualifier,
+the resulting type is the so-qualified atomic type.
+.PP
+If an attempt is made to assign
+.B NULL
+to a pointer defined with the
+.B \%nonnull
+qualifier,
+the behavior is undefined.
+If an attempt is made to refer to
+a pointer with a
+.RB non- \%nonnull -qualified
+type
+through the use of
+an lvalue with
+.BR \%nonnull -qualified
+type,
+the behavior is undefined.
+.PP
+The intended use of the
+.B \%nonnull
+and
+.B \%restrict
+qualifiers
+(like the
+.B \%register
+storage class)
+is to promote optimization,
+and deleting all instances of the qualifier
+from all preprocessing translation units composing a conforming program
+does not change its meaning (i.e., observable behavior).
+.SH NOTES
+These rules for
+.B nonnull
+are somewhat of the reverse of
+.BR const :
+Instead of forbidding the discarding of the qualifier,
+we forbid the addition of the qualifier.
+The reason is that constant variables are a subset of variables,
+and the danger is in treating a
+.B const
+as a variable.
+Similarly,
+.B nonnull
+pointers are a subset of
+.RB (possibly- NULL )
+pointers,
+but the danger is in treating
+.RB possibly- NULL
+pointers as
+.B \%nonnull
+pointers.
+.SS Prior art
+GCC has
+.BR [[gnu::nonnull]] .
+Why is this better?
+.PP
+It can be applied more specifically in the case of pointers to pointers.
+And, like with
+.BR const ,
+the
+.BR nonnull -ness
+can be better enforced by passing the qualifier around.
+.PP
+However, we recognize the optimizations allowed by
+.BR [[gnu::nonnull]] ,
+and also allow them,
+by specifying the behavior as undefined
+when the qualifier is misused,
+as GCC does.
+.PP
+Clang has
+.BR _Nonnull .
+Why is this better?
+.PP
+Clang found that using a qualifier was better than an attribute,
+since it allowed to more specifically apply it to pointers to pointers.
+We recognize that,
+and also use a qualifier.
+.PP
+Clang doesn't specify the behavior as being undefined.
+That forbids optimizations,
+that would otherwise be possible.
+We prefer to allow for those optimizations.
+.PP
+Clang considers this qualifier to be useful only as a diagnostics generator.
+We not only allow for diagnostics to be issued,
+but we have stricter rules that
+make it more difficult to produce incorrect code.
+.PP
+Even though the language has reserved identifiers
+starting with underscore + uppercase
+for this kind of keywords,
+Clang has already used
+.BR _Nonnull ,
+and since we are changing the meaning,
+it might cause problems to existing code.
+So
+.B nonnull
+seems a better name,
+which hopefully is not used by existing code,
+or at least it is less used.
+.SH EXAMPLES
+.SS Correct
+.BR strcpy (3)
+may be implemented in the following way,
+to signify that it cannot accept
+.B NULL
+as input to any of its arguments,
+and that it cannot ever return
+.B NULL
+either.
+.PP
+.EX
+char *nonnull strcpy(char *nonnull restrict dest,
+ const char *nonnull restrict src)
+{
+ char *d;
+
+ d = dest;
+ while ((*d++ = *src++) != '\e0');
+
+ return dest;
+}
+.EE
+.PP
+Note that
+.I d
+need not be
+.BR nonnull -qualified,
+since possibly being
+.B NULL
+is a superset of not possibly being
+.BR NULL .
+.PP
+The following variations of the above are incorrect,
+for the reasons that follow the code examples.
+.SS Incorrect
+.EX
+char *strcpy(char *nonnull restrict dest,
+ const char *nonnull restrict src)
+{
+ char *d;
+
+ d = dest;
+ while ((*d++ = *src++) != '\e0');
+
+ return dest;
+}
+.EE
+.PP
+Although this would be valid by itself
+(wouldn't have undefined behavior),
+it forbids callers of the function
+from assigning the return value to a
+.BR \%nonnull -qualified
+pointer.
+.PP
+.SS Undefined behavior
+.EX
+char *nonnull strcpy(char *restrict dest,
+ const char *nonnull restrict src)
+{
+ char *d;
+
+ d = dest;
+ while ((*d++ = *src++) != '\e0');
+
+ return dest;
+}
+.EE
+This causes undefined behavior,
+since it assigns a
+.RB non- \%nonnull -qualified
+pointer
+.RI ( dest )
+to a qualified one
+(the return value).
+It's also dangerous,
+since the user isn't properly informed that
+.B NULL
+may cause undefined behavior in the implementation of the function
+.RI ( dest
+is dereferenced).
+.SH AUTHORS
+Alejandro Colomar
+.UR alx.manpages@gmail.com
+.PP
+I must thank the GCC and Clang programmers
+for having provided a solid base
+on which I based this proposal.
+.SH SEE ALSO
+N2731 - 6.7.3
+.PP
+.UR https://gcc.gnu.org/\:onlinedocs/\:gcc/\:Common-Function-Attributes.html\:#Common-Function-Attributes
+.UE
+.PP
+.UR https://clang.llvm.org/\:docs/\:AttributeReference.html\:#nullability-attributes
+.UE