summaryrefslogblamecommitdiffstats
path: root/nonnull.7
blob: 1390b2d17b18461fc0bf7e4cc03d9154116d9de4 (plain) (tree)





























































                                                                       
            








                                                                
            









                             
                        





                                                                        
                   


                                                       
                        





                                       
                




















                                                                            
                


                                         
            





























                                                      
                         








































                                                      
   















                                                                  
   


                                          
                                      







                                                                                                         
.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
.PP
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
.UE
.PP
I must thank the GCC and Clang programmers
for having provided a solid base
on which I inspired for 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