Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

nullptr in C

156 views
Skip to first unread message

Thiago Adams

unread,
Aug 22, 2018, 8:53:12 AM8/22/18
to
Considering nullptr is a keyword in C++ and considering
many people (including me) try to keep the C code compiling
in C++ should we adopt it as a macro in C?

I can see some similarities with bool in C.

When I include:

#include <stdbool.h>

the code works with bool , true , false in C and C++.

So.. I was thinking in

#include <stdnull.h>

and create nullptr macro if the code is comping in C.

The other option could be define NULL as nullptr if the
compiler is C++ and use NULL everywhere.

Have you ever make this question to yourself?
What to do?



Message has been deleted

james...@alumni.caltech.edu

unread,
Aug 22, 2018, 10:30:49 AM8/22/18
to
My apologies to anyone who sees two versions of this message. I coughed
unexpectedly while drinking some milk, spewing milk everywhere, and
while I was cleaning up I apparently accidentally hit the "Post" button
on an incomplete version of this message.
The key point - the hard work associated with this proposal - will be
taking what the C++ standard says about nullptr, and figuring out how to
change the C standard to say something similar - ideally in a way that
is as compatible as possible with C++. This will get tricky, because
much of what it says about nullptr is said indirectly, through what it
says about prvalues and std::nullptr_t. It mentions std::nullptr_t in a
LOT of different places.

Consider a fully conforming implementation of C, and a fully-conforming
implementation of C++, which are as compatible with each other as is
permitted by both standards. I don't just mean that you can link code
written in the two languages by using "extern C" linkage appropriately
in the C++ code, though that is certainly implied. By compatible, I mean
that wherever there is a construct that is acceptable in both languages:
If the behavior of the construct according to either standard is
unspecified, each implementation makes a choice that's compatible with
that standard, if there is any such choice that is permitted by both
standards.
If either standard specifies that the behavior is implementation-
defined, both implementations make the same choice with regard to that
behavior, if there is any such choice that would be permitted by both
standards.

Currently, you can take almost any correct C program (as that term is
defined in 4p3 of the C standard), and with minor modifications, produce
a correct C program that is also well-formed C++ code, which will have
the same observable behavior with both of those compatible
implementations. Addition of nullptr to C should be done, if at all, in
a way that preserves this property.

Thiago Adams

unread,
Aug 22, 2018, 3:03:35 PM8/22/18
to
I was thinking about just create a header like this.

#ifndef __cplusplus
#define nullptr ((void *)0)
#endif

In C++ nullptr is nullptr and in C nullptr is synonym for NULL.

Scott Lurndal

unread,
Aug 22, 2018, 3:09:56 PM8/22/18
to
That will potentially break many thousands of programs
which already use an identifier named 'nullptr'.

Thiago Adams

unread,
Aug 22, 2018, 3:17:44 PM8/22/18
to
On Wednesday, August 22, 2018 at 4:09:56 PM UTC-3, Scott Lurndal wrote:
In this case, don't include this header in your
old code.

Jorgen Grahn

unread,
Aug 22, 2018, 3:27:15 PM8/22/18
to
On Wed, 2018-08-22, Thiago Adams wrote:
> Considering nullptr is a keyword in C++ and considering
> many people (including me) try to keep the C code compiling
> in C++ should we adopt it as a macro in C?

No. It's better that the few who do this avoid using 'nullptr' as an
identifier in their C code, just as they avoid 'class', 'throw' and so
on already.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Keith Thompson

unread,
Aug 22, 2018, 5:16:34 PM8/22/18
to
Jorgen Grahn <grahn...@snipabacken.se> writes:
> On Wed, 2018-08-22, Thiago Adams wrote:
>> Considering nullptr is a keyword in C++ and considering
>> many people (including me) try to keep the C code compiling
>> in C++ should we adopt it as a macro in C?
>
> No. It's better that the few who do this avoid using 'nullptr' as an
> identifier in their C code, just as they avoid 'class', 'throw' and so
> on already.

I don't make an particular effort to avoid 'class' or 'throw' in my C
code. In fact I've deliberately used "class" as an identifier to ensure
that it's compiled as C.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson

unread,
Aug 22, 2018, 5:19:35 PM8/22/18
to
Keith Thompson <ks...@mib.org> writes:
> Jorgen Grahn <grahn...@snipabacken.se> writes:
>> On Wed, 2018-08-22, Thiago Adams wrote:
>>> Considering nullptr is a keyword in C++ and considering
>>> many people (including me) try to keep the C code compiling
>>> in C++ should we adopt it as a macro in C?
>>
>> No. It's better that the few who do this avoid using 'nullptr' as an
>> identifier in their C code, just as they avoid 'class', 'throw' and so
>> on already.
>
> I don't make an particular effort to avoid 'class' or 'throw' in my C
> code. In fact I've deliberately used "class" as an identifier to ensure
> that it's compiled as C.

Of course I wouldn't do that if I intended my code to be compilable both
as C and as C++, but I rarely if ever need to do that.

Bart

unread,
Aug 22, 2018, 5:32:59 PM8/22/18
to
What about those wonderful refactoring tools that people talk about; are
they not capable of globally renaming a variable?

And what about when incorporating someone else's code, or using their
headers; what happens when their global names clash with yours? For
example, both lots use 'nullptr' for different purposes.

It is also possible to use the language version to enable or disable
newer features. You can disable them when compiling older code.

(And if there really are thousands of programs already using 'nullptr',
it is a reasonable guess it is for the same purpose, and that
demonstrates a need for such a thing.)

--
bart

Thiago Adams

unread,
Mar 22, 2019, 3:14:48 PM3/22/19
to
I changed my mind and I don't think adding nullptr is a good idea.

One difference between adding _Bool into the language is that BOOL
was never added into the language headers. (Am I right? I didn't find
BOOL or TRUE FALSE at the language specification).

On the other hand if you search for NULL at the standard you will
find that NULL is defined in stddef.h

This means that adding _Bool didn't added a new way to declare booleans,
but adding nullptr will create this confusion that is two ways of
writing code that means NULL.

In C we also have different ((void*)0) conversion rules compared with
C++ that is more strict.

Then for C, I believe that the literal that corresponds nullptr already
exists and it is ((void*)0).

What could be done is adding flags to static analysis to decide what
to do with ((void*)0) conversions.




James Kuyper

unread,
Mar 22, 2019, 4:29:35 PM3/22/19
to
On Friday, March 22, 2019 at 3:14:48 PM UTC-4, Thiago Adams wrote:
> On Wednesday, August 22, 2018 at 9:53:12 AM UTC-3, Thiago Adams wrote:
> > Considering nullptr is a keyword in C++ and considering
> > many people (including me) try to keep the C code compiling
> > in C++ should we adopt it as a macro in C?
> >
> > I can see some similarities with bool in C.
> >
> > When I include:
> >
> > #include <stdbool.h>
> >
> > the code works with bool , true , false in C and C++.
> >
> > So.. I was thinking in
> >
> > #include <stdnull.h>
> >
> > and create nullptr macro if the code is comping in C.
> >
> > The other option could be define NULL as nullptr if the
> > compiler is C++ and use NULL everywhere.
> >
> > Have you ever make this question to yourself?
> > What to do?
>
> I changed my mind and I don't think adding nullptr is a good idea.
>
> One difference between adding _Bool into the language is that BOOL
> was never added into the language headers. (Am I right? I didn't find
> BOOL or TRUE FALSE at the language specification).

That's true, but only because C is a case sensitive language.

Section 7.18:

"The header <stdbool.h> defines four macros.
2 The macro
bool
expands to _Bool.
3 The remaining three macros are suitable for use in #if
preprocessing directives. They are
true
which expands to the integer constant 1,
false
which expands to the integer constant 0, and
_ _bool_true_false_are_defined
which expands to the integer constant 1."

> This means that adding _Bool didn't added a new way to declare booleans,

Actually, C has two ways to declare booleans, both of which were added to the language at the same time: _Bool and bool.

> but adding nullptr will create this confusion that is two ways of
> writing code that means NULL.

I think you mean "means a null pointer constant". NULL and nullptr would
be two different macros that both expand to be a null pointer constant,
but there's already a huge variety of ways of writing one (for instance,
('\004'/5ULL)); having one additional way wouldn't be a big deal.

The key thing that drove the addition of nullptr to C++ was the fact
that NULL was required to expand to an expression with integer type and
a value of 0. Such an expression can always be used as either a null
pointer constant and as an ordinary integer. nullptr can only be used as
a null pointer constant.

In C, NULL is already allowed to expand to (void*)0, which is not an
integer, so a simpler change than adding nullptr would be to require
that NULL expand to an expression with pointer type. No strictly
conforming code would be broken by such a change. C++ didn't have that
option.

Thiago Adams

unread,
Mar 24, 2019, 7:52:10 AM3/24/19
to
Yes, I was discarding the direct use of _Bool in my mind.
Does anyone uses _Bool instead of bool ?

Thinking in this way, if we had _Null we could leave
it just to implement NULL and not use it directly, but I
cannot see other advantages over ((void*)0). Like you said
C doesn't have the same needs of C++.

What worries me is the mess caused by may types of styles
inside the same source code. I think many companies using
C++ are facing these questions of style.

William Ahern

unread,
Mar 25, 2019, 10:00:15 AM3/25/19
to
Thiago Adams <thiago...@gmail.com> wrote:
> On Friday, March 22, 2019 at 5:29:35 PM UTC-3, James Kuyper wrote:
<snip>
>> Actually, C has two ways to declare booleans, both of which were added to
>> the language at the same time: _Bool and bool.
>
> Yes, I was discarding the direct use of _Bool in my mind.
> Does anyone uses _Bool instead of bool ?

I use _Bool to avoid ambiguity and potential correctness issues for when a
header is compiled with C++.

I also prefer _Static_assert over static_assert after encountering an issue
between a glibc <assert.h> header and GCC versions. (I forget whether the
issue was an old glibc and new GCC or new glibc and old GCC.)

> Thinking in this way, if we had _Null we could leave
> it just to implement NULL and not use it directly, but I
> cannot see other advantages over ((void*)0). Like you said
> C doesn't have the same needs of C++.
>
> What worries me is the mess caused by may types of styles
> inside the same source code. I think many companies using
> C++ are facing these questions of style.

The magnitude of consistency issues in C++ is simply incomparable to C.

Using _Bool over bool is mostly an aesthetic issue that one can get over
very quickly. While there may be good reasons for using one over the other,
those reasons mostly implicate language interoperability issues and don't
reflect substantive C language complexity (e.g. not an example of TMTOWTDI).
Someone doesn't need to understand why one was chosen over the other--as far
as C is concerned they have identical behavior, and that's the end of it.

Indeed, _Bool vs bool, _Static_assert vs static_assert, etc, are more
reflective of C++ or C/C++ interoperability than of C, per se.

James Kuyper

unread,
Mar 25, 2019, 2:37:16 PM3/25/19
to
On Sunday, March 24, 2019 at 7:52:10 AM UTC-4, Thiago Adams wrote:
> On Friday, March 22, 2019 at 5:29:35 PM UTC-3, James Kuyper wrote:
> > On Friday, March 22, 2019 at 3:14:48 PM UTC-4, Thiago Adams wrote:
...
> > > This means that adding _Bool didn't added a new way to declare booleans,
> >
> > Actually, C has two ways to declare booleans, both of which were added to the language at the same time: _Bool and bool.
>
> Yes, I was discarding the direct use of _Bool in my mind.
> Does anyone uses _Bool instead of bool ?

Yes, I routinely use _Bool, if only to avoid having to
#include <stdbool.h>. In my experience, the need to avoid a conflicting
definition of "bool" comes up only rarely, but often enough to justify
avoiding it's use. I almost never need to write code that will compile
as both C and C++ code, with the same meaning.

Thiago Adams

unread,
Mar 25, 2019, 3:02:11 PM3/25/19
to
In this case, what do you use for 'true' and 'false' ?

(Both macros are defined in stdbool.h)




James Kuyper

unread,
Mar 25, 2019, 3:23:33 PM3/25/19
to
if(condition)
if(!condition)

Assuming the condition variable is suitably named, that should be a very
clear, obvious way of using it.

Ian Collins

unread,
Mar 25, 2019, 3:33:56 PM3/25/19
to
As a function parameter?

> Assuming the condition variable is suitably named, that should be a very
> clear, obvious way of using it.

--
Ian.


James Kuyper

unread,
Mar 25, 2019, 3:58:57 PM3/25/19
to
function(boolean_expression)

I'm not saying the issue never comes up, but in most cases where I've
used _Bool, explicit use of either true or false is unnecessary. This is
probably the result of writing C code for more than three decades, and
not having "true" or "false" available as part of the language for most
of that time (the last time I worked on MODIS code, I was still covered
by a 1997 coding guideline that required me to write for C94 (C90 + first
two TC's)). I got pretty good at writing code that didn't need to use
them, which isn't very difficult.
The C++ code that I'm working on right now makes extensive use of true
or false to initialize bool variables in all constructors - even for
non-static data members that are explicitly set to some other value later
on in the same constructor.

Keith Thompson

unread,
Mar 25, 2019, 4:15:11 PM3/25/19
to
James Kuyper <james...@alumni.caltech.edu> writes:
> On Monday, March 25, 2019 at 3:02:11 PM UTC-4, Thiago Adams wrote:
[...]
>> In this case, what do you use for 'true' and 'false' ?
>>
>> (Both macros are defined in stdbool.h)
>
> if(condition)
> if(!condition)
>
> Assuming the condition variable is suitably named, that should be a very
> clear, obvious way of using it.

What about this?

_Bool condition = false;

Do you just never find a need to write something like that?

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

James Kuyper

unread,
Mar 25, 2019, 4:21:48 PM3/25/19
to
On Monday, March 25, 2019 at 4:15:11 PM UTC-4, Keith Thompson wrote:
> James Kuyper <james...@alumni.caltech.edu> writes:
> > On Monday, March 25, 2019 at 3:02:11 PM UTC-4, Thiago Adams wrote:
> [...]
> >> In this case, what do you use for 'true' and 'false' ?
> >>
> >> (Both macros are defined in stdbool.h)
> >
> > if(condition)
> > if(!condition)
> >
> > Assuming the condition variable is suitably named, that should be a very
> > clear, obvious way of using it.
>
> What about this?
>
> _Bool condition = false;
>
> Do you just never find a need to write something like that?

Not "never", but "seldom".

Ian Collins

unread,
Mar 25, 2019, 5:25:59 PM3/25/19
to
A smell for discussion in another place!

--
Ian.

0 new messages