Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #401372 > unrolled thread

Initialization Of Static Pointer Variables

Started byLawrence D’Oliveiro <ldo@nz.invalid>
First post2026-08-20 23:14 +0000
Last post2026-08-21 06:02 -0700
Articles 20 on this page of 29 — 12 participants

Back to article view | Back to comp.lang.c


Contents

  Initialization Of Static Pointer Variables Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-08-20 23:14 +0000
    Re: Initialization Of Static Pointer Variables "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-20 16:28 -0700
      Re: Initialization Of Static Pointer Variables "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-20 16:29 -0700
    Re: Initialization Of Static Pointer Variables richard@cogsci.ed.ac.uk (Richard Tobin) - 2026-08-20 23:42 +0000
      Re: Initialization Of Static Pointer Variables "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2026-08-21 12:12 -0700
        Re: Initialization Of Static Pointer Variables David Brown <david.brown@hesbynett.no> - 2026-08-22 13:12 +0200
          Re: Initialization Of Static Pointer Variables steve g <Sgonedes1977@gmail.com> - 2026-08-23 16:01 -0400
            Re: Initialization Of Static Pointer Variables Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-08-23 22:16 +0000
            Re: Initialization Of Static Pointer Variables Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-23 15:29 -0700
              Re: Initialization Of Static Pointer Variables David Brown <david.brown@hesbynett.no> - 2026-08-24 10:16 +0200
                Re: Initialization Of Static Pointer Variables Richard Harnden <richard.nospam@gmail.invalid> - 2026-08-24 09:45 +0100
                  Re: Initialization Of Static Pointer Variables Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-24 03:04 -0700
                    Re: Initialization Of Static Pointer Variables David Brown <david.brown@hesbynett.no> - 2026-08-24 12:40 +0200
                      Re: Initialization Of Static Pointer Variables Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-24 13:16 -0700
            Re: Initialization Of Static Pointer Variables richard@cogsci.ed.ac.uk (Richard Tobin) - 2026-08-23 22:28 +0000
            Cryptographic zero initialization (was: Re: Initialization Of Static Pointer Variables) Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-24 19:26 +0800
    Re: Initialization Of Static Pointer Variables Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-20 16:52 -0700
    Re: Initialization Of Static Pointer Variables James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-08-20 20:12 -0400
    Re: Initialization Of Static Pointer Variables bart <bc@freeuk.com> - 2026-08-21 01:16 +0100
      Re: Initialization Of Static Pointer Variables Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-08-20 17:53 -0700
      Re: Initialization Of Static Pointer Variables James Kuyper <jameskuyper@alumni.caltech.edu> - 2026-08-20 23:01 -0400
        Re: Initialization Of Static Pointer Variables Lawrence D’Oliveiro <ldo@nz.invalid> - 2026-08-21 08:02 +0000
          Re: Initialization Of Static Pointer Variables scott@slp53.sl.home (Scott Lurndal) - 2026-08-21 14:53 +0000
            Re: Initialization Of Static Pointer Variables richard@cogsci.ed.ac.uk (Richard Tobin) - 2026-08-21 15:28 +0000
      Re: Initialization Of Static Pointer Variables David Brown <david.brown@hesbynett.no> - 2026-08-21 09:12 +0200
    Re: Initialization Of Static Pointer Variables David Brown <david.brown@hesbynett.no> - 2026-08-21 09:03 +0200
      Re: Initialization Of Static Pointer Variables Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-21 17:54 +0800
    Re: Initialization Of Static Pointer Variables Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> - 2026-08-21 17:50 +0800
    Re: Initialization Of Static Pointer Variables Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-08-21 06:02 -0700

Page 1 of 2  [1] 2  Next page →


#401372 — Initialization Of Static Pointer Variables

FromLawrence D’Oliveiro <ldo@nz.invalid>
Date2026-08-20 23:14 +0000
SubjectInitialization Of Static Pointer Variables
Message-ID<11681np$3s8jk$4@dont-email.me>
The C spec goes out of its way to make clear that a NULL pointer does
not necessarily have the same bit pattern as the integer value zero.
This in spite of the fact that it is allowed to test a pointer value
for NULL by comparing it to the integer value zero.

The spec also says that all static variables are initialized to zero
at program start time. Are pointer variables allowed to be given an
all-zero bit pattern at this time? Or are they supposed to be
initialized to the NULL value (if that’s different) instead?

[toc] | [next] | [standalone]


#401373

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2026-08-20 16:28 -0700
Message-ID<11682j8$3t93j$1@dont-email.me>
In reply to#401372
On 8/20/2026 4:14 PM, Lawrence D’Oliveiro wrote:
> The C spec goes out of its way to make clear that a NULL pointer does
> not necessarily have the same bit pattern as the integer value zero.
> This in spite of the fact that it is allowed to test a pointer value
> for NULL by comparing it to the integer value zero.
> 
> The spec also says that all static variables are initialized to zero
> at program start time. Are pointer variables allowed to be given an
> all-zero bit pattern at this time? Or are they supposed to be
> initialized to the NULL value (if that’s different) instead?


static int g_a = 0;

int main()
{
     int a = g_a;

     // oh my... a can be anything wrt the std?

     return 0;
}

[toc] | [prev] | [next] | [standalone]


#401374

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2026-08-20 16:29 -0700
Message-ID<11682kf$3t93j$2@dont-email.me>
In reply to#401373
On 8/20/2026 4:28 PM, Chris M. Thomasson wrote:
> On 8/20/2026 4:14 PM, Lawrence D’Oliveiro wrote:
>> The C spec goes out of its way to make clear that a NULL pointer does
>> not necessarily have the same bit pattern as the integer value zero.
>> This in spite of the fact that it is allowed to test a pointer value
>> for NULL by comparing it to the integer value zero.
>>
>> The spec also says that all static variables are initialized to zero
>> at program start time. Are pointer variables allowed to be given an
>> all-zero bit pattern at this time? Or are they supposed to be
>> initialized to the NULL value (if that’s different) instead?
> 
> 
> static int g_a = 0;
> 
> int main()
> {
>      int a = g_a;
> 
>      // oh my... a can be anything wrt the std?
> 
>      return 0;
> }


Oh shit! I did not mean to init g_a to zero here. Sorry!

;^o ouch.

[toc] | [prev] | [next] | [standalone]


#401375

Fromrichard@cogsci.ed.ac.uk (Richard Tobin)
Date2026-08-20 23:42 +0000
Message-ID<11683d0$jki7$1@artemis.inf.ed.ac.uk>
In reply to#401372
In article <11681np$3s8jk$4@dont-email.me>,
Lawrence D;Oliveiro  <ldo@nz.invalid> wrote:

>The spec also says that all static variables are initialized to zero
>at program start time. Are pointer variables allowed to be given an
>all-zero bit pattern at this time? Or are they supposed to be
>initialized to the NULL value (if that's different) instead?

ISO C 1999, 6.7.8:

If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate. If an object that has static
storage duration is not initialized explicitly, then:

— if it has pointer type, it is initialized to a null pointer;

— if it has arithmetic type, it is initialized to (positive or
unsigned) zero;

— if it is an aggregate, every member is initialized (recursively)
according to these rules;

— if it is a union, the first named member is initialized
(recursively) according to these rules

-- Richard

[toc] | [prev] | [next] | [standalone]


#401412

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2026-08-21 12:12 -0700
Message-ID<116a7vj$iojj$1@dont-email.me>
In reply to#401375
On 8/20/2026 4:42 PM, Richard Tobin wrote:
> In article <11681np$3s8jk$4@dont-email.me>,
> Lawrence D;Oliveiro  <ldo@nz.invalid> wrote:
> 
>> The spec also says that all static variables are initialized to zero
>> at program start time. Are pointer variables allowed to be given an
>> all-zero bit pattern at this time? Or are they supposed to be
>> initialized to the NULL value (if that's different) instead?
> 
> ISO C 1999, 6.7.8:
> 
> If an object that has automatic storage duration is not initialized
> explicitly, its value is indeterminate. If an object that has static
> storage duration is not initialized explicitly, then:
> 
> — if it has pointer type, it is initialized to a null pointer;

Oh. I must have missed that one.

so:

static void* g_ptr;


is guaranteed to be nullptr? Just to clarify...


> 
> — if it has arithmetic type, it is initialized to (positive or
> unsigned) zero;
> 
> — if it is an aggregate, every member is initialized (recursively)
> according to these rules;
> 
> — if it is a union, the first named member is initialized
> (recursively) according to these rules


[...]

[toc] | [prev] | [next] | [standalone]


#401423

FromDavid Brown <david.brown@hesbynett.no>
Date2026-08-22 13:12 +0200
Message-ID<116c07d$1274o$1@dont-email.me>
In reply to#401412
On 21/08/2026 21:12, Chris M. Thomasson wrote:
> On 8/20/2026 4:42 PM, Richard Tobin wrote:
>> In article <11681np$3s8jk$4@dont-email.me>,
>> Lawrence D;Oliveiro  <ldo@nz.invalid> wrote:
>>
>>> The spec also says that all static variables are initialized to zero
>>> at program start time. Are pointer variables allowed to be given an
>>> all-zero bit pattern at this time? Or are they supposed to be
>>> initialized to the NULL value (if that's different) instead?
>>
>> ISO C 1999, 6.7.8:
>>
>> If an object that has automatic storage duration is not initialized
>> explicitly, its value is indeterminate. If an object that has static
>> storage duration is not initialized explicitly, then:
>>
>> — if it has pointer type, it is initialized to a null pointer;
> 
> Oh. I must have missed that one.
> 
> so:
> 
> static void* g_ptr;
> 
> 
> is guaranteed to be nullptr? Just to clarify...
> 
Yes.

[toc] | [prev] | [next] | [standalone]


#401444

Fromsteve g <Sgonedes1977@gmail.com>
Date2026-08-23 16:01 -0400
Message-ID<87y0dwsj1t.fsf@gmail.com>
In reply to#401423
David Brown <david.brown@hesbynett.no> writes:

> On 21/08/2026 21:12, Chris M. Thomasson wrote:
>> On 8/20/2026 4:42 PM, Richard Tobin wrote:
>>> In article <11681np$3s8jk$4@dont-email.me>,
>>> Lawrence D;Oliveiro  <ldo@nz.invalid> wrote:
>>>
>>>> The spec also says that all static variables are initialized to zero
>>>> at program start time. Are pointer variables allowed to be given an
>>>> all-zero bit pattern at this time? Or are they supposed to be
>>>> initialized to the NULL value (if that's different) instead?
>>>
>>> ISO C 1999, 6.7.8:
>>>
>>> If an object that has automatic storage duration is not initialized
>>> explicitly, its value is indeterminate. If an object that has static
>>> storage duration is not initialized explicitly, then:
>>>
>>> — if it has pointer type, it is initialized to a null pointer;
>> Oh. I must have missed that one.
>> so:
>> static void* g_ptr;
>> is guaranteed to be nullptr? Just to clarify...
>> 
> Yes.

I would still recomend memset or bzero. You never know what is complient
or not - better to be safe then sorry.

[toc] | [prev] | [next] | [standalone]


#401447

FromLawrence D’Oliveiro <ldo@nz.invalid>
Date2026-08-23 22:16 +0000
Message-ID<116frg8$29a3t$3@dont-email.me>
In reply to#401444
On Sun, 23 Aug 2026 16:01:18 -0400, steve g wrote:

> I would still recomend memset or bzero. You never know what is
> complient or not - better to be safe then sorry.

This kind of practice can have its own unintended consequences.

It’s quite common for the BSS area to be allocated using “demand-zero”
pages on modern OSes. This means no actual pages are allocated to
begin with; instead, the page table entry is set to indicate that the
page allocation (and initialization) will happen on the first actual
access to that page.

So if you explicitly initialize pages that are supposed to be zero
anyway, you could be causing a lot of unnecessary page faulting, and
also increasing your program’s physical memory usage, without actually
gaining anything.

[toc] | [prev] | [next] | [standalone]


#401448

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-08-23 15:29 -0700
Message-ID<116fs7n$29df6$1@kst.eternal-september.org>
In reply to#401444
steve g <Sgonedes1977@gmail.com> writes:
> David Brown <david.brown@hesbynett.no> writes:
>> On 21/08/2026 21:12, Chris M. Thomasson wrote:
>>> On 8/20/2026 4:42 PM, Richard Tobin wrote:
[...]
>>> Oh. I must have missed that one.
>>> so:
>>> static void* g_ptr;
>>> is guaranteed to be nullptr? Just to clarify...
>>> 
>> Yes.
>
> I would still recomend memset or bzero. You never know what is complient
> or not - better to be safe then sorry.

Bad idea.

bzero is non-standard.  It was never in ISO C, and has been removed
from POSIX.

Calling memset() to set a pointer object to the null pointer fails
if a null pointer is not represented as all-bits-zero.  An explicit
initialization to 0, NULL, or nullptr (C23 or later) is clearer and
more portable.  Implementations that don't use all-bits-zero for null
pointers are rare, but so are implementations that don't zero-init
uninitialized static objects -- and the former can be conforming.

There are apparently a handful of C implementations for very
small embedded systems that do not zero static objects.  If you're
using such an implementation, you're very probably aware of it,
and you certainly should be.  Your "You never know" statement above
is incorrect.  I suspect that most code written for such systems
doesn't need to be portable.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#401452

FromDavid Brown <david.brown@hesbynett.no>
Date2026-08-24 10:16 +0200
Message-ID<116gukj$2jomr$1@dont-email.me>
In reply to#401448
On 24/08/2026 00:29, Keith Thompson wrote:
> steve g <Sgonedes1977@gmail.com> writes:
>> David Brown <david.brown@hesbynett.no> writes:
>>> On 21/08/2026 21:12, Chris M. Thomasson wrote:
>>>> On 8/20/2026 4:42 PM, Richard Tobin wrote:
> [...]
>>>> Oh. I must have missed that one.
>>>> so:
>>>> static void* g_ptr;
>>>> is guaranteed to be nullptr? Just to clarify...
>>>>
>>> Yes.
>>
>> I would still recomend memset or bzero. You never know what is complient
>> or not - better to be safe then sorry.
> 
> Bad idea.
> 
> bzero is non-standard.  It was never in ISO C, and has been removed
> from POSIX.
> 
> Calling memset() to set a pointer object to the null pointer fails
> if a null pointer is not represented as all-bits-zero.  An explicit
> initialization to 0, NULL, or nullptr (C23 or later) is clearer and
> more portable.  Implementations that don't use all-bits-zero for null
> pointers are rare, but so are implementations that don't zero-init
> uninitialized static objects -- and the former can be conforming.
> 
> There are apparently a handful of C implementations for very
> small embedded systems that do not zero static objects.  If you're
> using such an implementation, you're very probably aware of it,
> and you certainly should be.  Your "You never know" statement above
> is incorrect.  I suspect that most code written for such systems
> doesn't need to be portable.
> 

You probably also know if you are coding for one of the few systems that 
do not use all zero bits for null pointers - AFAIK they are basically 
museum relics.  (Of course there are still a few museum relics in 
current use, but you would know it if you were coding for them.)

Still, using memset or bzero to write zeros to data that is initialised 
by pre-main startup is worse than useless.  It does nothing useful, 
takes a bit of extra time, may spoil some optimisations (compilers can 
sometimes eliminate or simplify file-static variables, but probably not 
if they have been the target of memset or bzero), makes a maintenance a 
pain (you have to add new calls for each new variable), risks someone 
making smart-arse and unwarranted assumptions (such as trying to combine 
variables in a single memset/bzero call), and can easily confuse readers 
who can't see why the code is doing this.

It is true that pretty much every C compiler has its non-conformances, 
with some having more than others.  But pretty much all (baring the 
aforementioned embedded toolchains) are going to get something this 
basic entirely correct.  If you can't be entirely confident of a 
toolchain getting this right, you should - if possible - switch toolchains.

(Fortunately in the embedded world, most development is moving to gcc or 
occasionally clang, with some industries sticking to the "big" 
commercial toolchain vendors.  The weird and highly non-conforming are 
much rarer, and becoming horror stories to scare the new kids.)

[toc] | [prev] | [next] | [standalone]


#401455

FromRichard Harnden <richard.nospam@gmail.invalid>
Date2026-08-24 09:45 +0100
Message-ID<116h0br$2m8pa$1@dont-email.me>
In reply to#401452
On 24/08/2026 09:16, David Brown wrote:
> On 24/08/2026 00:29, Keith Thompson wrote:
>> steve g <Sgonedes1977@gmail.com> writes:
>>> David Brown <david.brown@hesbynett.no> writes:
>>>> On 21/08/2026 21:12, Chris M. Thomasson wrote:
>>>>> On 8/20/2026 4:42 PM, Richard Tobin wrote:
>> [...]
>>>>> Oh. I must have missed that one.
>>>>> so:
>>>>> static void* g_ptr;
>>>>> is guaranteed to be nullptr? Just to clarify...
>>>>>
>>>> Yes.
>>>
>>> I would still recomend memset or bzero. You never know what is complient
>>> or not - better to be safe then sorry.
>>
>> Bad idea.
>>
>> bzero is non-standard.  It was never in ISO C, and has been removed
>> from POSIX.
>>
>> Calling memset() to set a pointer object to the null pointer fails
>> if a null pointer is not represented as all-bits-zero.  An explicit
>> initialization to 0, NULL, or nullptr (C23 or later) is clearer and
>> more portable.  Implementations that don't use all-bits-zero for null
>> pointers are rare, but so are implementations that don't zero-init
>> uninitialized static objects -- and the former can be conforming.
>>
>> There are apparently a handful of C implementations for very
>> small embedded systems that do not zero static objects.  If you're
>> using such an implementation, you're very probably aware of it,
>> and you certainly should be.  Your "You never know" statement above
>> is incorrect.  I suspect that most code written for such systems
>> doesn't need to be portable.
>>
> 
> You probably also know if you are coding for one of the few systems that 
> do not use all zero bits for null pointers - AFAIK they are basically 
> museum relics.  (Of course there are still a few museum relics in 
> current use, but you would know it if you were coding for them.)
> 
> Still, using memset or bzero to write zeros to data that is initialised 
> by pre-main startup is worse than useless.  It does nothing useful, 
> takes a bit of extra time, may spoil some optimisations (compilers can 
> sometimes eliminate or simplify file-static variables, but probably not 
> if they have been the target of memset or bzero), makes a maintenance a 
> pain (you have to add new calls for each new variable), risks someone 
> making smart-arse and unwarranted assumptions (such as trying to combine 
> variables in a single memset/bzero call), and can easily confuse readers 
> who can't see why the code is doing this.
> 
> It is true that pretty much every C compiler has its non-conformances, 
> with some having more than others.  But pretty much all (baring the 
> aforementioned embedded toolchains) are going to get something this 
> basic entirely correct.  If you can't be entirely confident of a 
> toolchain getting this right, you should - if possible - switch toolchains.
> 
> (Fortunately in the embedded world, most development is moving to gcc or 
> occasionally clang, with some industries sticking to the "big" 
> commercial toolchain vendors.  The weird and highly non-conforming are 
> much rarer, and becoming horror stories to scare the new kids.)
> 

Can you safely say something like this ... ?

struct foo
{
     char *s;
     int n;
     char c;
     void *data;
};

static const struct foo FOO_INIT;

int main(void)
{
     struct foo foo;

     foo = FOO_INIT;

     ...


[toc] | [prev] | [next] | [standalone]


#401456

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-08-24 03:04 -0700
Message-ID<116h4ui$2nla6$1@kst.eternal-september.org>
In reply to#401455
Richard Harnden <richard.nospam@gmail.invalid> writes:
[...]
> Can you safely say something like this ... ?
>
> struct foo
> {
>     char *s;
>     int n;
>     char c;
>     void *data;
> };
>
> static const struct foo FOO_INIT;
>
> int main(void)
> {
>     struct foo foo;
>
>     foo = FOO_INIT;
>
>     ...

That's safe for conforming implementations.  You can also
use an initializer:

    struct foo foo = FOO_INIT;

It solves the problem of zero-initializing a non-static object
(such objects contain garbage if they're not initialized) -- but
it's better done by writing

    struct foo foo = { 0 };

(In C23 and later you can omit the 0.)

If you need a zero-initialized struct foo value as an expression,
e.g. for use in an assigment or as an argument, you can use a
compound literal in C99 or later:

    foo = (struct foo){ 0 };

Again, you can omit the 0 in C23 or later.

Here you're relying on the implementation to zero unspecified
members, which is required by the standard.

If you're stuck using a non-conforming implementation, you need
to know exactly *how* it's non-conforming, and write whatever
ugly code you need to work around it.  Different non-conforming
implementations are likely to be non-conforming in surprising ways.
(Ideally your ugly code will also work on conforming implementations,
but that might not be a priority.)

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#401457

FromDavid Brown <david.brown@hesbynett.no>
Date2026-08-24 12:40 +0200
Message-ID<116h720$2o3jf$1@dont-email.me>
In reply to#401456
On 24/08/2026 12:04, Keith Thompson wrote:
> Richard Harnden <richard.nospam@gmail.invalid> writes:
> [...]
>> Can you safely say something like this ... ?
>>
>> struct foo
>> {
>>      char *s;
>>      int n;
>>      char c;
>>      void *data;
>> };
>>
>> static const struct foo FOO_INIT;
>>
>> int main(void)
>> {
>>      struct foo foo;
>>
>>      foo = FOO_INIT;
>>
>>      ...
> 
> That's safe for conforming implementations.  You can also
> use an initializer:
> 
>      struct foo foo = FOO_INIT;
> 
> It solves the problem of zero-initializing a non-static object
> (such objects contain garbage if they're not initialized) -- but
> it's better done by writing
> 
>      struct foo foo = { 0 };
> 
> (In C23 and later you can omit the 0.)

In what sense do you consider that "better" ?  I think it is arguably 
neater and less cognitive effort to understand, but did you have 
anything else in mind?

As I understand it, there is a distinction between :

	struct foo foo;
	foo = FOO_INIT;		// or foo = (struct foo) { 0 };

and

	struct foo foo = FOO_INIT;	// or foo = { 0 };

in that the former just copies the value of FOO_INIT while the later 
guarantees zero bit initialisation for padding bits and bytes.

It's unlikely that an optimising compiler would generate different code 
in practice.

> 
> If you need a zero-initialized struct foo value as an expression,
> e.g. for use in an assigment or as an argument, you can use a
> compound literal in C99 or later:
> 
>      foo = (struct foo){ 0 };
> 
> Again, you can omit the 0 in C23 or later.
> 
> Here you're relying on the implementation to zero unspecified
> members, which is required by the standard.
> 
> If you're stuck using a non-conforming implementation, you need
> to know exactly *how* it's non-conforming, and write whatever
> ugly code you need to work around it.  Different non-conforming
> implementations are likely to be non-conforming in surprising ways.
> (Ideally your ugly code will also work on conforming implementations,
> but that might not be a priority.)
> 

[toc] | [prev] | [next] | [standalone]


#401469

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-08-24 13:16 -0700
Message-ID<116i8qv$365ov$1@kst.eternal-september.org>
In reply to#401457
David Brown <david.brown@hesbynett.no> writes:
> On 24/08/2026 12:04, Keith Thompson wrote:
>> Richard Harnden <richard.nospam@gmail.invalid> writes:
>> [...]
>>> Can you safely say something like this ... ?
>>>
>>> struct foo
>>> {
>>>      char *s;
>>>      int n;
>>>      char c;
>>>      void *data;
>>> };
>>>
>>> static const struct foo FOO_INIT;
>>>
>>> int main(void)
>>> {
>>>      struct foo foo;
>>>
>>>      foo = FOO_INIT;
>>>
>>>      ...
>> That's safe for conforming implementations.  You can also
>> use an initializer:
>>      struct foo foo = FOO_INIT;
>> It solves the problem of zero-initializing a non-static object
>> (such objects contain garbage if they're not initialized) -- but
>> it's better done by writing
>>      struct foo foo = { 0 };
>> (In C23 and later you can omit the 0.)
>
> In what sense do you consider that "better" ?  I think it is arguably
> neater and less cognitive effort to understand, but did you have
> anything else in mind?

Not really.  With { 0 }, you can see at a glance what it means.
With FOO_INIT, you have to know how FOO_INIT is defined, possibly in
a different source file.

Of course if the initial value is something other than all-zeros, you
can change the way FOO_INIT is defined, and { 0 } wouldn't work.

> As I understand it, there is a distinction between :
>
> 	struct foo foo;
> 	foo = FOO_INIT;		// or foo = (struct foo) { 0 };
>
> and
>
> 	struct foo foo = FOO_INIT;	// or foo = { 0 };
>
> in that the former just copies the value of FOO_INIT while the later
> guarantees zero bit initialisation for padding bits and bytes.
>
> It's unlikely that an optimising compiler would generate different
> code in practice.

I hadn't thought about that (and it's not likely to matter).  I don't
remember the rules for initializing padding off the top of my head.

[...]

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#401449

Fromrichard@cogsci.ed.ac.uk (Richard Tobin)
Date2026-08-23 22:28 +0000
Message-ID<116fs5l$nr16$1@artemis.inf.ed.ac.uk>
In reply to#401444
In article <87y0dwsj1t.fsf@gmail.com>, steve g  <Sgonedes1977@gmail.com> wrote:
>>> static void* g_ptr;
>>> is guaranteed to be nullptr? Just to clarify...

>> Yes.

>I would still recomend memset or bzero. You never know what is complient
>or not - better to be safe then sorry.

Absolutely not.  memset(..., 0, ...) or bzero(...) will produce all
zeroes, which is not necessarily a null pointer.

These set p to a null pointer:

static void *p;
void *p = 0;

This is not guaranteed to:

void *p;
memset(&p, 0, sizeof(p));

-- Richard

[toc] | [prev] | [next] | [standalone]


#401458 — Cryptographic zero initialization (was: Re: Initialization Of Static Pointer Variables)

FromJohann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid>
Date2026-08-24 19:26 +0800
SubjectCryptographic zero initialization (was: Re: Initialization Of Static Pointer Variables)
Message-ID<ETViS.1242773$yWz9.271063@fx04.ams4>
In reply to#401444
On 24/08/2026 4:01 AM, steve g wrote:
> David Brown <david.brown@hesbynett.no> writes:
> 
>> On 21/08/2026 21:12, Chris M. Thomasson wrote:
>>> On 8/20/2026 4:42 PM, Richard Tobin wrote:
>>>> In article <11681np$3s8jk$4@dont-email.me>,
>>>> Lawrence D;Oliveiro  <ldo@nz.invalid> wrote:
>>>>
>>>>> The spec also says that all static variables are initialized to zero
>>>>> at program start time. Are pointer variables allowed to be given an
>>>>> all-zero bit pattern at this time? Or are they supposed to be
>>>>> initialized to the NULL value (if that's different) instead?
>>>>
>>>> ISO C 1999, 6.7.8:
>>>>
>>>> If an object that has automatic storage duration is not initialized
>>>> explicitly, its value is indeterminate. If an object that has static
>>>> storage duration is not initialized explicitly, then:
>>>>
>>>> — if it has pointer type, it is initialized to a null pointer;
>>> Oh. I must have missed that one.
>>> so:
>>> static void* g_ptr;
>>> is guaranteed to be nullptr? Just to clarify...
>>>
>> Yes.
> 
> I would still recomend memset or bzero. You never know what is complient
> or not - better to be safe then sorry.

And if your need is cryptographic security, you should be using Micro-
soft's SecureZeroMemory() or its equivalent,

  
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/aa366877(v=vs.85)

and never mind the legacy warning, it's still there in the header files,
and it's just a fancy way to write STOSB, so I'm including alt.lang.asm,
and comp.lang.asm in this discussion; this is to annoy the trolls in
comp.lang.c.

Of course, many of the trolls in comp.lang.c are Linux supremacists, so
they're going to have to figure out what GCC offers for the equivalent
functionality.

After all, /SecureZeroMemory()/ cannot be optimized out, or it wouldn't
be secure.

I'm actually curious about the equivalent function in GCC, since one of
my many hobbies is cryptographic programming.


Happy programming cryptography in assembly!
-- 
Johann | email: invalid -> com | http://www.myrkraverk.com/blog/
I'm not from the Internet, I just work there. | via Easynews.com
https://bsky.app/profile/myrkraverk.bsky.social | for ( ;; ) _:;

[toc] | [prev] | [next] | [standalone]


#401376

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-08-20 16:52 -0700
Message-ID<1168407$3scp8$1@kst.eternal-september.org>
In reply to#401372
Lawrence D’Oliveiro <ldo@nz.invalid> writes:
> The C spec goes out of its way to make clear that a NULL pointer does
> not necessarily have the same bit pattern as the integer value zero.
> This in spite of the fact that it is allowed to test a pointer value
> for NULL by comparing it to the integer value zero.

I don't know that it "goes out of its way" to say this.  I haven't done
an exhaustive check, but as I recall it just doesn't say anything about
the representation of a null pointer (a more precise term than "NULL
pointer"), except to say that it's unspecified.  Possibly some care has
been taken to avoid implying anything more specific.

> The spec also says that all static variables are initialized to zero
> at program start time. Are pointer variables allowed to be given an
> all-zero bit pattern at this time? Or are they supposed to be
> initialized to the NULL value (if that’s different) instead?

This is very clearly stated in the standard.  N3220 6.7.11p11 :

    If an object that has automatic storage duration is not initialized
    explicitly, its representation is indeterminate. If an object that
    has static or thread storage duration is not initialized explicitly,
    or any object is initialized with an empty initializer, then it is
    subject to default initialization, which initializes an object as
    follows:

    -- if it has pointer type, it is initialized to a null pointer;
    
All other types are either numeric (and are initialized to zero of
the type), or are aggregates, for which initialization is defined
recursively.

An implementation that stored all-bits-zero in an ununinitialized
static pointer object would be non-conforming if that weren't the
representation of a null pointer.  This:

#include <stdio.h>
int main(void) {
    static void *ptr;
    if (ptr != NULL) puts("OOPS");
    if (ptr != 0)    puts("OOPS");
}

must not print "OOPS".

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#401377

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2026-08-20 20:12 -0400
Message-ID<116854s$3u03l$1@dont-email.me>
In reply to#401372
On 2026-08-20 19:14, Lawrence D’Oliveiro wrote:
> The C spec goes out of its way to make clear that a NULL pointer does
> not necessarily have the same bit pattern as the integer value zero.
> This in spite of the fact that it is allowed to test a pointer value
> for NULL by comparing it to the integer value zero.

Not exactly. an integer constant expression with a value of zero is
recognized as a null pointer constant. When compared with a value of
pointer type, a null pointer constant gets converted into a null pointer
of that type BEFORE carrying out the comparison, so what is actually
being compared are two different pointer values. Note that if an integer
expression with a value of 0 doesn't qualify as a constant expression,
conversion to a pointer type produces an implementation-defined
behavior; it's not required to result in a null pointer value.

> The spec also says that all static variables are initialized to zero
> at program start time. Are pointer variables allowed to be given an
> all-zero bit pattern at this time? Or are they supposed to be
> initialized to the NULL value (if that’s different) instead?

"If an object that has static or thread storage duration is not
initialized explicitly, or any object is initialized with an empty
initializer, then it is subject to _default initialization_, which
initializes an object as follows:

— if it has pointer type, it is initialized to a null pointer;
— if it has type nullptr_t, it is initialized to nullptr;
— if it has decimal floating type, it is initialized to positive zero,
and the quantum exponent is implementation-defined;171)
— if it has arithmetic type, and it does not have decimal floating type,
it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively)
according to these rules, and any padding is initialized to zero bits;
— if it is a union, the first member that is not an unnamed bit-field is
initialized (recursively) according to these rules, and any padding is
initialized to zero bits." (6.7.11p14)

Note that this does not apply to all static variables, only those that
are not explicitly initialized with non-empty initializers.

The phrase "default initialization" is italicized, an ISO convention
indicating that this sentence constitutes the official definition of
that phrase.
It specifies zero bits only for aggregate and union padding. For any
object with a type, it specifies that it store a representation of 0,
which might not have all bits 0.

[toc] | [prev] | [next] | [standalone]


#401378

Frombart <bc@freeuk.com>
Date2026-08-21 01:16 +0100
Message-ID<11685cs$3tt8j$1@dont-email.me>
In reply to#401372
On 21/08/2026 00:14, Lawrence D’Oliveiro wrote:
> The C spec goes out of its way to make clear that a NULL pointer does
> not necessarily have the same bit pattern as the integer value zero.
> This in spite of the fact that it is allowed to test a pointer value
> for NULL by comparing it to the integer value zero.
> 
> The spec also says that all static variables are initialized to zero
> at program start time. Are pointer variables allowed to be given an
> all-zero bit pattern at this time? Or are they supposed to be
> initialized to the NULL value (if that’s different) instead?

The language would need to ensure that whatever bit-pattern is needed 
for NULL, would be written. This means for example that:

static void* A[100000000];

can't occupy the special .bss segment in an executable that takes almost 
no space; it would need 0.4 to 0.8GB of init data.

In general it would be a massive PITA, if you have for example arrays of 
nested structs which have mixed pointer/non-pointer members.

Imagine allocating such an array like this:

     p = malloc(N*sizeof(T));

and you wanted to set all elements to zeros and NULLs. You couldn't for 
example do:

     memset(p, 0, N*sizeof(T));

as the pointers would not be NULL.

[toc] | [prev] | [next] | [standalone]


#401379

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2026-08-20 17:53 -0700
Message-ID<11687iu$3u68b$1@kst.eternal-september.org>
In reply to#401378
bart <bc@freeuk.com> writes:
> On 21/08/2026 00:14, Lawrence D’Oliveiro wrote:
>> The C spec goes out of its way to make clear that a NULL pointer does
>> not necessarily have the same bit pattern as the integer value zero.
>> This in spite of the fact that it is allowed to test a pointer value
>> for NULL by comparing it to the integer value zero.
>> The spec also says that all static variables are initialized to zero
>> at program start time. Are pointer variables allowed to be given an
>> all-zero bit pattern at this time? Or are they supposed to be
>> initialized to the NULL value (if that’s different) instead?
>
> The language would need to ensure that whatever bit-pattern is needed
> for NULL, would be written.

Correct -- except that I'd say "ensures" rather than "would need to
ensure".

>                             This means for example that:
>
> static void* A[100000000];
>
> can't occupy the special .bss segment in an executable that takes
> almost no space; it would need 0.4 to 0.8GB of init data.

True.  Of course the ".bss segment" is an implementation detail, not
part of the language.

> In general it would be a massive PITA, if you have for example arrays
> of nested structs which have mixed pointer/non-pointer members.
>
> Imagine allocating such an array like this:
>
>     p = malloc(N*sizeof(T));
>
> and you wanted to set all elements to zeros and NULLs. You couldn't
> for example do:
>
>     memset(p, 0, N*sizeof(T));
>
> as the pointers would not be NULL.

Yes, all these are practical disadvantages of using a representation
other than all-bits-zero for null pointers, and are undoubtedly
some of the reasons why the vast majority of C implementations *do*
use all-bits-zero for null pointers.

But a conforming implementation could of course use a different
representation, and it would then have to do whatever it needs to
to make it work.

Using memset() to set pointers to null isn't portable as far as the
language is concerned.  It may well be portable enough for your
purposes, and you might never encounter a system where it fails.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web