![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
By my reading, neither C nor C++ guarantee the following:
union {
long x;
char* y;
} xyz;
xyz.y = NULL;
printf("%ld\n", xyz.x);
Neither C nor C++ guarantees that'll be zero (assuming
sizeof(char*)==sizeof(long)). In other words, neither guarantees that the
bit pattern in memory for NULL is actually all zeros, right?
So using memset() to clear a structure to 0 that contains pointers isn't
guaranteed to be portable to something like the AT&T 3B2, where NULL != 0x0
in memory?
I looked, but all I found were references to "null pointer value", and not
any bit patterns.
--
Darren New, San Diego CA, USA (PST)
"We'd like you to back-port all the changes in 2.0
back to version 1.0."
"We've done that already. We call it 2.0."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Le 30/07/2009 22:14, Darren New nous fit lire :
> By my reading, neither C nor C++ guarantee the following:
>
> union {
> long x;
> char* y;
> } xyz;
> xyz.y = NULL;
> printf("%ld\n", xyz.x);
>
> Neither C nor C++ guarantees that'll be zero (assuming
> sizeof(char*)==sizeof(long)). In other words, neither guarantees that
> the bit pattern in memory for NULL is actually all zeros, right?
>
> So using memset() to clear a structure to 0 that contains pointers isn't
> guaranteed to be portable to something like the AT&T 3B2, where NULL !=
> 0x0 in memory?
Well, it will be portable. memset() will work.
But if later you expect to check the pointer against NULL, you will be disappointed.
That's also why modern compiler can issue warning about usage of potentialy
uninitialised
variables.
In C++, you could make a class for your structure, and have a nice constructor to set
NULL in y; But that might somehow conflict with the usage of the union...
Is it really worth having an union there ? How do you, within the limit of strong
typing,
expect the union to behave ?
Only "legit" union I can know are sock_addr fields, allowing access to
8/16/32-bits-word
arrays.
Mixing a value and a pointer is a non-sense, unless you provide a real & sensible
usage.
>
> I looked, but all I found were references to "null pointer value", and
> not any bit patterns.
>
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Le_Forgeron wrote:
> Well, it will be portable. memset() will work.
> But if later you expect to check the pointer against NULL, you will be disappointed.
Well, yes, that's what I was asking.
> In C++, you could make a class for your structure, and have a nice constructor to
set
> NULL in y; But that might somehow conflict with the usage of the union...
The union was just an unambiguous demonstration of what I meant by "the bit
pattern of a NULL pointer in memory." It's not actual code.
> Mixing a value and a pointer is a non-sense, unless you provide a real & sensible
usage.
memset() was more what I was talking about, which clearly mixes pointers and
values if you apply it to a structure with pointers in it.
--
Darren New, San Diego CA, USA (PST)
"We'd like you to back-port all the changes in 2.0
back to version 1.0."
"We've done that already. We call it 2.0."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
From: Fredrik Eriksson
Subject: Re: Quick C language-lawyer question...
Date: 30 Jul 2009 16:39:33
Message: <op.uxweb7gw7bxctx@e6600>
|
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
On Thu, 30 Jul 2009 22:14:16 +0200, Darren New <dne### [at] san rr com> wrote:
> In other words, neither guarantees that the bit pattern in memory for
> NULL is actually all zeros, right?
Right.
> So using memset() to clear a structure to 0 that contains pointers isn't
> guaranteed to be portable to something like the AT&T 3B2, where NULL !=
> 0x0 in memory?
Assuming that you want the pointers to have null pointer values, it is
only portable to architectures that explicitly specify an all-zero bit
pattern for null pointers.
> I looked, but all I found were references to "null pointer value", and
> not any bit patterns.
The standard does not specify any particular bit pattern, so naturally
there is no mention of such things.
--
FE
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Fredrik Eriksson <fe79}--at--{yahoo}--dot--{com> wrote:
> On Thu, 30 Jul 2009 22:14:16 +0200, Darren New <dne### [at] san rr com> wrote:
> > In other words, neither guarantees that the bit pattern in memory for
> > NULL is actually all zeros, right?
> Right.
OTOH, how many modern architectures have null pointers which are not
all-zeros?
If you are writing C which must be portable to obscure embedded systems,
microwave ovens, 30-years-old obsolete mainframes and such, then you will
have to take that and a whole lot of other things into account. OTOH, if
you are just writing C for the PC, Mac and a few Unix computers out there,
the rules can often be relaxed a bit.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> By my reading, neither C nor C++ guarantee the following:
>
> union {
> long x;
> char* y;
> } xyz;
> xyz.y = NULL;
> printf("%ld\n", xyz.x);
>
> Neither C nor C++ guarantees that'll be zero (assuming
> sizeof(char*)==sizeof(long)). In other words, neither guarantees that the
> bit pattern in memory for NULL is actually all zeros, right?
Absolutely right. Although it is common on most architectures to use an all-zero
value to represent a null pointer value, the specification only requires that
the binary representation is not used for any other purposes.
Just as you cannot rely on the char type to be an 8-bit integer. Or pointers to
be of the same size as long int, for that matter.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> OTOH, how many modern architectures have null pointers which are not
> all-zeros?
Now, me, being cynical, would say it's more "how many broken programs caused
enough trouble that future architectures made sure that 0 is the bit pattern
for null pointers?" :-) I was using a AT&T 3B2 in the early 90's that had
non-zero null pointers, but I think that's the only machine I ever used that
supported C that didn't use 0. Given they were insurance company computers,
I wouldn't be surprised if they're still around. Legacy business systems
have a way of living on for much longer than you'd think.
> you are just writing C for the PC, Mac and a few Unix computers out there,
> the rules can often be relaxed a bit.
Sure. It's language lawyering, not practical development. That's why I
called it that. :-)
On the other hand, I wonder if segmented pointers (as in near and far
pointers) used a segment of 0 to mean null for far pointers, or guaranteed
that CS:0 and DS:0 (or whtever) would map to invalid pages. Hmmm...
--
Darren New, San Diego CA, USA (PST)
"We'd like you to back-port all the changes in 2.0
back to version 1.0."
"We've done that already. We call it 2.0."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> > you are just writing C for the PC, Mac and a few Unix computers out there,
> > the rules can often be relaxed a bit.
> Sure. It's language lawyering, not practical development. That's why I
> called it that. :-)
Some would also say that if you have to worry about the bit-pattern of
null pointers, that's questionable optimization.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
clipka <nomail@nomail> wrote:
> Just as you cannot rely on the char type to be an 8-bit integer. Or pointers to
> be of the same size as long int, for that matter.
Or all pointers having the same size. (For example, in C++ member function
pointers will typically be larger than a void*. This surprises even many
experienced C++ programmers.)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Some would also say that if you have to worry about the bit-pattern of
> null pointers, that's questionable optimization.
The only reason I brought it up is this grody code I'm trying to make work
has a number of places where it initializes a structure to zero with
memset(), and the structure has pointers in it.
Given that the structure is a description of the hardware built into the
machine, it's not going to be portable to different CPUs anyway, but I just
got curious as to whether I'd misunderstood last time I looked thru the
specs. People often mistakenly argue that C++ guarantees the bit pattern is
zero because you now write { char* x = 0; } instead of { char* x = NULL; }
--
Darren New, San Diego CA, USA (PST)
"We'd like you to back-port all the changes in 2.0
back to version 1.0."
"We've done that already. We call it 2.0."
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |