Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #401372 > unrolled thread
| Started by | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| First post | 2026-08-20 23:14 +0000 |
| Last post | 2026-08-21 06:02 -0700 |
| Articles | 20 on this page of 29 — 12 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-08-20 23:14 +0000 |
| Subject | Initialization 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]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2026-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]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2026-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]
| From | richard@cogsci.ed.ac.uk (Richard Tobin) |
|---|---|
| Date | 2026-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]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2026-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2026-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]
| From | steve g <Sgonedes1977@gmail.com> |
|---|---|
| Date | 2026-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]
| From | Lawrence D’Oliveiro <ldo@nz.invalid> |
|---|---|
| Date | 2026-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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2026-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]
| From | Richard Harnden <richard.nospam@gmail.invalid> |
|---|---|
| Date | 2026-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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2026-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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-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]
| From | richard@cogsci.ed.ac.uk (Richard Tobin) |
|---|---|
| Date | 2026-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]
| From | Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.invalid> |
|---|---|
| Date | 2026-08-24 19:26 +0800 |
| Subject | Cryptographic 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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2026-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]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2026-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]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2026-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