Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Is the aliasing rule symmetric?

Reply
Thread Tools

Is the aliasing rule symmetric?

 
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-25-2011
James Kanze <> writes:

> On Jan 25, 3:15 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>> This is cross posted and I don't think the C side of the questions have
>> been properly answered. My answer is about C only.

>
> Hopefully, C++ says the same thing. This is one point where
> I don't think the languages should differ.
>
>> Joshua Maurice <joshuamaur...@gmail.com> writes:
>> > On Jan 24, 2:49 am, James Kanze <james.ka...@gmail.com> wrote:
>> >> On Jan 22, 10:29 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
>> >> > Let's consider this function though:
>> >> > int foo(int* x, short* y)
>> >> > {
>> >> > *x = 1;
>> >> > *y = 2;
>> >> > return 1;
>> >> > }
>> >> > int bar(int* x, short* y)
>> >> > {
>> >> > *x = 1;
>> >> > *y = 2;
>> >> > return *x;
>> >> > }
>> >> > Let's consider functions foo and bar. Let's suppose that x and
>> >> > y alias in both. For function foo, there is no undefined
>> >> > behavior even though both alias (at least according to what
>> >> > appears to be the prominent interpretation of these rules).

>
>> >> I'm not sure about C here, but in C++, there is definitely
>> >> undefined behavior in foo if x and y alias.

>
>> If x and y both point to the same allocated object, then neither
>> function is undefined. The assignments set the "effective type" of the
>> allocated object.

>
> Gcc treates it as undefined behavior if there is aliasing, and
> may reorder the assignments. (IMHO, this is an error, but from
> what I understand, it is an important optimization in certan
> cases.)


How annoying. I was trying to clarify things and I went and miss-read
the code -- I read the *x return as *y. bar *is* undefined but I was
correct about foo: it is not undefined (in C).

Gcc may re-order the statements because in foo the order does not matter
and in bar the return causes UB.

>> >> In fact, there
>> >> would be undefined behavior even if foo were simply:

>
>> >> void foo(const int* x, const short* y)
>> >> {
>> >> printf("%d, %d\n", *x, *y)
>> >> }

>
>> Again, this is not always UB when the object being aliased is allocated
>> rather than declared.

>
> I'm not sure I understand. Supposing that x and y point to the
> same address, which was obtained by malloc. If the memory is
> uninitialized, there is undefined behavior.


What I should have said is that the code is not always UB. Yes it can
be UB (and it is in almost every imaginable case where you might see
this code) but it does not have to be.

> If the memory was
> initialized as an int, then accessing it as a short is undefined
> behavior, and if it was initialized as a short, accessing it as
> an int has undefined behavior. And there's no way for its
> "effective type" to be both short and int; it's one or the
> other (or none of the above), but it can't be both.


Yes, the effective type can't be two types at once but it can be none.
If the object is zeroed with memset before the call (or it was allocated
using calloc) it still has no effective type (at least this is my
reading of the situation) and so the "effective type of the object is
simply the type of the lvalue used for the access".

>> When the aliased object is allocated, whether the
>> accesses are defined or not depends on the effective type of the aliased
>> allocated object. To be certain of UB when the pointers point to the
>> same allocated object you need something like this:

>
>> void foo(int *x, short *y)
>> {
>> *y = 1;
>> printf("%d\n", *x);
>> }

>
>> The assignment ensures that the effective type of the allocated object
>> is int so the the second is undefined.

>
>> >> If the two pointers point to the same physical address, there is
>> >> no way that the memory they point to can be both an int and
>> >> a short.

>
>> In C it can be if the storage is allocated and only stores are done (as
>> in the first foo and bar above).

>
> In C (and C++), when the memory is allocated, it is
> uninitialized. I don't know what type, if any, it is assumed to
> have, but regardless of the type, you simply cannot access
> uninitialized memory (except through an unsigned char*). And
> once you initialize it, you've fixed the type (until the next
> "initialization", at least).


I don't think memset sets the effective type. A clearer example might
be to use callocd space rather than mallocd space, but in either case if
all you do is stores (like the first foo function above) then C defines
the result. C++'s rules are (naturally) much more complicated and I
don't pretend to understand them yet, but from other posts I gather that
C++ also permits such code -- the write though the pointer effectively
starting a new object lifetime.

What is the effect of memset(..., 0, ...) on such an object in C++? In
C++ what accesses are permitted after zeroing with memset? I think that
in C the effective type is erased (the object will have no effective
type) and the access rules are written to handle that case explicitly.
That wording is not there in C++ and I can't yet work out the
consequences of that difference.

>> >> And the C++ standard clearly says:
>> >> If a program attempts to access the stored value of an
>> >> object through an lvalue of other than one of the following
>> >> types the behavior is undefined:
>> >> [...]
>> >> and short for int or vice versa isn't in the list. And I'm
>> >> certain that the intent in C is the same: C definitly allows
>> >> trapping representations for integer values, and reading part of
>> >> an int as a short could conceivably result in a trapping
>> >> representation for a short. (Think of a one's complement
>> >> machine which traps on -0.)

>
>> >> The problem becomes more interesting if we replace short with
>> >> unsigned char. In that case, my version is legal and defined
>> >> behavior: accessing a stored value through an lvalue of char or
>> >> unsgiend char type is in the list after the cited paragraph.
>> >> (IIRC, in C, this exception only applies to unsigned char; for
>> >> some reason, C++ added plain char to the list.)

>
>> In C, the wording is "a character type" which covers char and both
>> signed and unsigned char. As you say, it is odd (at last at first
>> glance -- I am not a C++ expert) that C++ added char but not signed
>> char to the list.

>
> It's especially odd that signed char is allowed, since copying
> a signed char cannot necessarily be made to preserve the raw
> bits or avoid trapping.


I don't think it's odd, but that is ultimately a matter of opinion. I
think it's simpler to include all char types or, alternatively, to
permit only unsigned char which neither language has done (for entirely
reasonable historical reasons).

> (Again, a machine with 1's complement
> which either converts all 0's the positive representation when
> it sees them, or traps. On such machines, for plain char to
> work, it would have to be unsigned---in fact, on the two
> machines I know which don't use 2's complement, plain char is
> unsigned.)
>
> Just an idea: for purposes of demonstration, it might be better
> to use int and float, rather than int and short, because reading
> an int as a float can trap on most common machines; we don't
> have to introduce such exotics as 1's complement to cause
> issues.


I think traps complicate rather than clarify the argument. It would be
better to restrict the discussion to the access -- is the access itself
permitted or undefined -- rather than add the complication of whether
the result is a trap representation. After all, many accesses that are
unquestionably well-defined can yield a trap representation and many
unquestionably undefined accesses don't involve traps in any way.

To understand C and C++'s access rules I'd suggest we pick examples
where traps don't enter into the picture -- say by using integer types
and declaring that there are no trap representations.

--
Ben.
 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-25-2011
Joshua Maurice <> writes:

> On Jan 24, 8:10Â*pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:

<snip>
>> Have you got some reason to suspect that there is a problem with any of
>> these programs in C? Â*The C standard seems quite clear on these specific
>> questions.

>
> Yes. I've been getting various replies when I tweak the above program
> just slightly.
>
> #include <stdlib.h>
> void foo(int* a, float* b)
> {
> *a = 1;
> *b = 1;
> }
> int main()
> {
> void* p = malloc(sizeof(int) + sizeof(float));
> foo((int*)p, (float*)p);
> }
>
> I asked if this had UB in comp.lang.c a while ago. I received various
> replies, with little follow up discussion.
>
> One reply was that a piece of memory may have at most one effective
> type between calls to malloc and free.


That seems to me to be clearly false. Here is the wording:

"The effective type of an object for an access to its stored value is
the declared type of the object, if any[75]. If a value is stored into
an object having no declared type through an lvalue having a type that
is not a character type, then the type of the lvalue becomes the
effective type of the object for that access and for subsequent
accesses that do not modify the stored value. If a value is copied
into an object having no declared type using memcpy or memmove, or is
copied as an array of character type, then the effective type of the
modified object for that access and for subsequent accesses that do
not modify the value is the effective type of the object from which
the value is copied, if it has one. For all other accesses to an
object having no declared type, the effective type of the object is
simply the type of the lvalue used for the access."

Footnote 75 says: "Allocated objects have no declared type."

The object being stored into has no declared type. The *a = 1; makes
the effective type of the allocated space 'int' for that access and for
subsequent accesses that do not modify the object, but *b = 1; does
modify the object so, again, the effective types becomes that of the
lvalue expression used in the store: 'float'.

> Another reply was that this is a DR in the C and C++ language specs,
> known colloquially as the union DR.


There is no union so unless the DR covers more than just unions it won't
apply.

> Another reply was that the above program has perfectly well defined
> behavior, but the following has undefined behavior:


> #include <stdlib.h>
> int foo(int* a, float* b)
> {
> *a = 1;
> *b = 1;
> return *a;
> }
> int main()
> {
> void* p = malloc(sizeof(int) + sizeof(float));
> foo((int*)p, (float*)p);
> }


Yes, that's undefined. Sadly, I miss-read a similar example elsewhere
in this thread. After *b = 1; the effective type is float and the
access through an lvalue expression on type int is undefined.

> Specifically, this example explains how the compiler might use
> aliasing analysis for optimization purposes. A conforming compiler may
> not simply assume that an int* and a float* do not alias. However, if
> analysis shows that aliasing would result in UB (as it would in the
> above program when "return *a;" reads a float object through an int
> lvalue) then the compiler is free to do whatever it wants in the face
> of the UB, including assume that they don't alias.
>
> I think I like the third option best, but my personal preferences
> don't dictate what compilers actually do.


No, nor mine, but that last explanation seems to me to be the correct
one.

An example that might distinguish between a compiler that assumes no
aliasing and one that knows the effective type rules would be this:

#include <stdlib.h>
#include <stdio.h>

int foo(int *a, float *b)
{
int x = *a;
*b = 1;
return x + *b;
}

int main(void)
{
void *p = malloc(sizeof(int) + sizeof(float));
*(int *)p = 1;
printf("%d\n", foo((int *)p, (float *)p));
printf("%f\n", *(float *)p);
return 0;
}

I think James posted a similar example elsewhere. In C this is
well-define and must print 2 and 1.000000 (or thereabouts). If a
compiler just assumes that 'a' and 'b' in foo can never point to the
same object, it might produce the wrong result (by, for example,
optimising 'x' away and using *a in the return).

It is possible that the C committee intended that the rules would allow
a compiler to assume that 'a' and 'b' don't alias, but that is certainly
not how I read the rules as they stand.

--
Ben.
 
Reply With Quote
 
 
 
 
Johannes Schaub (litb)
Guest
Posts: n/a
 
      01-25-2011
Ben Bacarisse wrote:

> James Kanze <> writes:
>
>> On Jan 25, 3:15 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>>> This is cross posted and I don't think the C side of the questions have
>>> been properly answered. My answer is about C only.

>>
>> Hopefully, C++ says the same thing. This is one point where
>> I don't think the languages should differ.
>>
>>> Joshua Maurice <joshuamaur...@gmail.com> writes:
>>> > On Jan 24, 2:49 am, James Kanze <james.ka...@gmail.com> wrote:
>>> >> On Jan 22, 10:29 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
>>> >> > Let's consider this function though:
>>> >> > int foo(int* x, short* y)
>>> >> > {
>>> >> > *x = 1;
>>> >> > *y = 2;
>>> >> > return 1;
>>> >> > }
>>> >> > int bar(int* x, short* y)
>>> >> > {
>>> >> > *x = 1;
>>> >> > *y = 2;
>>> >> > return *x;
>>> >> > }
>>> >> > Let's consider functions foo and bar. Let's suppose that x and
>>> >> > y alias in both. For function foo, there is no undefined
>>> >> > behavior even though both alias (at least according to what
>>> >> > appears to be the prominent interpretation of these rules).

>>
>>> >> I'm not sure about C here, but in C++, there is definitely
>>> >> undefined behavior in foo if x and y alias.

>>
>>> If x and y both point to the same allocated object, then neither
>>> function is undefined. The assignments set the "effective type" of the
>>> allocated object.

>>
>> Gcc treates it as undefined behavior if there is aliasing, and
>> may reorder the assignments. (IMHO, this is an error, but from
>> what I understand, it is an important optimization in certan
>> cases.)

>
> How annoying. I was trying to clarify things and I went and miss-read
> the code -- I read the *x return as *y. bar *is* undefined but I was
> correct about foo: it is not undefined (in C).
>
> Gcc may re-order the statements because in foo the order does not matter
> and in bar the return causes UB.
>


I don't think so. In foo the order does matter if both x and y point to the
same allocated object. The caller of the function might want to access the
memory later on with a short lvalue. Reordering the assignments will cause
UB in the caller.

>> If the memory was
>> initialized as an int, then accessing it as a short is undefined
>> behavior, and if it was initialized as a short, accessing it as
>> an int has undefined behavior. And there's no way for its
>> "effective type" to be both short and int; it's one or the
>> other (or none of the above), but it can't be both.

>
> Yes, the effective type can't be two types at once but it can be none.
> If the object is zeroed with memset before the call (or it was allocated
> using calloc) it still has no effective type (at least this is my
> reading of the situation) and so the "effective type of the object is
> simply the type of the lvalue used for the access".
>


I didn't consider this at all before. Interesting!

>>> When the aliased object is allocated, whether the
>>> accesses are defined or not depends on the effective type of the aliased
>>> allocated object. To be certain of UB when the pointers point to the
>>> same allocated object you need something like this:

>>
>>> void foo(int *x, short *y)
>>> {
>>> *y = 1;
>>> printf("%d\n", *x);
>>> }

>>
>>> The assignment ensures that the effective type of the allocated object
>>> is int so the the second is undefined.

>>
>>> >> If the two pointers point to the same physical address, there is
>>> >> no way that the memory they point to can be both an int and
>>> >> a short.

>>
>>> In C it can be if the storage is allocated and only stores are done (as
>>> in the first foo and bar above).

>>


A store modifies the effective type of an object. The spec says "If a value
is stored into an object having no declared type through an lvalue having a
type that is not a character type, then the type of the lvalue becomes ...",
therefor if you store an int, and then store a float, the object's effective
type isn't int anymore but becomes a float. It can't be two. At least that
wouldn't make sense to me.

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      01-25-2011
"Johannes Schaub (litb)" <schaub-> writes:

> Ben Bacarisse wrote:
>
>> James Kanze <> writes:
>>
>>> On Jan 25, 3:15 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>>>> This is cross posted and I don't think the C side of the questions have
>>>> been properly answered. My answer is about C only.
>>>
>>> Hopefully, C++ says the same thing. This is one point where
>>> I don't think the languages should differ.
>>>
>>>> Joshua Maurice <joshuamaur...@gmail.com> writes:
>>>> > On Jan 24, 2:49 am, James Kanze <james.ka...@gmail.com> wrote:
>>>> >> On Jan 22, 10:29 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
>>>> >> > Let's consider this function though:
>>>> >> > int foo(int* x, short* y)
>>>> >> > {
>>>> >> > *x = 1;
>>>> >> > *y = 2;
>>>> >> > return 1;
>>>> >> > }
>>>> >> > int bar(int* x, short* y)
>>>> >> > {
>>>> >> > *x = 1;
>>>> >> > *y = 2;
>>>> >> > return *x;
>>>> >> > }
>>>> >> > Let's consider functions foo and bar. Let's suppose that x and
>>>> >> > y alias in both. For function foo, there is no undefined
>>>> >> > behavior even though both alias (at least according to what
>>>> >> > appears to be the prominent interpretation of these rules).
>>>
>>>> >> I'm not sure about C here, but in C++, there is definitely
>>>> >> undefined behavior in foo if x and y alias.
>>>
>>>> If x and y both point to the same allocated object, then neither
>>>> function is undefined. The assignments set the "effective type" of the
>>>> allocated object.
>>>
>>> Gcc treates it as undefined behavior if there is aliasing, and
>>> may reorder the assignments. (IMHO, this is an error, but from
>>> what I understand, it is an important optimization in certan
>>> cases.)

>>
>> How annoying. I was trying to clarify things and I went and miss-read
>> the code -- I read the *x return as *y. bar *is* undefined but I was
>> correct about foo: it is not undefined (in C).
>>
>> Gcc may re-order the statements because in foo the order does not matter
>> and in bar the return causes UB.
>>

>
> I don't think so. In foo the order does matter if both x and y point to the
> same allocated object. The caller of the function might want to access the
> memory later on with a short lvalue. Reordering the assignments will cause
> UB in the caller.


Good point -- I missed that. I'd word it rather differently though.
The UB (or lack of it) is a property of the text (the program's text)
and not a property that can be caused by what a compiler chooses to do.
I'd phrase it like this: the caller must see the value 2 when accessing
the allocated object via an lvalue expression of type short. If it uses
a char type, it must see (one of) the representations of a short int
with value 2. Any other result means that the implementation is
non-conforming.

>>> If the memory was
>>> initialized as an int, then accessing it as a short is undefined
>>> behavior, and if it was initialized as a short, accessing it as
>>> an int has undefined behavior. And there's no way for its
>>> "effective type" to be both short and int; it's one or the
>>> other (or none of the above), but it can't be both.

>>
>> Yes, the effective type can't be two types at once but it can be none.
>> If the object is zeroed with memset before the call (or it was allocated
>> using calloc) it still has no effective type (at least this is my
>> reading of the situation) and so the "effective type of the object is
>> simply the type of the lvalue used for the access".
>>

>
> I didn't consider this at all before. Interesting!
>
>>>> When the aliased object is allocated, whether the
>>>> accesses are defined or not depends on the effective type of the aliased
>>>> allocated object. To be certain of UB when the pointers point to the
>>>> same allocated object you need something like this:
>>>
>>>> void foo(int *x, short *y)
>>>> {
>>>> *y = 1;
>>>> printf("%d\n", *x);
>>>> }
>>>
>>>> The assignment ensures that the effective type of the allocated object
>>>> is int so the the second is undefined.
>>>
>>>> >> If the two pointers point to the same physical address, there is
>>>> >> no way that the memory they point to can be both an int and
>>>> >> a short.
>>>
>>>> In C it can be if the storage is allocated and only stores are done (as
>>>> in the first foo and bar above).
>>>

>
> A store modifies the effective type of an object. The spec says "If a value
> is stored into an object having no declared type through an lvalue having a
> type that is not a character type, then the type of the lvalue becomes ...",
> therefor if you store an int, and then store a float, the object's effective
> type isn't int anymore but becomes a float. It can't be two. At least that
> wouldn't make sense to me.


Yes, it can't be two at the same time. I hope I did not imply it might
be (though I completely missed the point of the function bar so who know
what impression that gave). Code that only does stores into an
allocated object won't fall foul of the access rules. I think we are in
agreement about that.

--
Ben.
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      01-25-2011
On Jan 25, 11:17 am, Joshua Maurice <joshuamaur...@gmail.com> wrote:
> On Jan 25, 2:22 am, James Kanze <james.ka...@gmail.com> wrote:


> > If you're actually trying to write an allocator, you also have
> > to take into account what actual compilers do, and not just the
> > standard. I seem to recall something along the following lines:


> > float f(float const* in, bool* out)
> > {
> > float result = *in;
> > *out = true;
> > return result;
> > }


> > failing with g++ when called with:


> > union U { float f; bool b; };
> > U u;
> > u.f = 3.14159;
> > float g = f(&u.f, &u.b);


> > According to both C and C++, the union guaranteed that this
> > should work, But g++ rearranged the read and the write in f.


> > (I also seem to recall---albeit vaguely---the C committee saying
> > that it wasn't the intent to make this work; that they only
> > meant for it to be guaranteed if e.g. f was passed a pointer to
> > the union. But it's all very vague---I didn't have time to
> > follow up at the time.)


> > At any rate, most of this discussion seems to turn around the
> > same issues, without the union.


> Indeed. It's all very related to the union DR. So, the C standard
> committee never intended for the following program to have defined
> behavior? Interesting.


> void foo(int* x, float* y)
> { *x = 1;
> *y = 1;
> }
> int main()
> { union { int x; float y; } u;
> foo(&u.x, &u.y);
> return u.y;
> }


That's what I vaguely remember. But I don't remember who was
saying this (someone authorized to speak for the committe, or
not?), nor the exact context (other than it was in relationship
with the gcc bug). The best might be to take the discussion to
comp.std.c (although I don't read that).

And once we find out what was intended for C, we then have to
address the issue in C++; I'm still supposing that C++ wants
full C compatibility in this regard. (Or is that wishful
thinking on my part.)

--
James Kanze
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-25-2011
James Kanze <> writes:
> On Jan 24, 11:44 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:

[...]
>> We need to solve a couple of basic problems. The most important and
>> basic is: when does the lifetime of a POD class even begin?


Do you mean the lifetime of a POD *object*?

> That's a good question: do PODs have lifetime? I'd argue yes,
> but it's not the lifetime defined in §3.8. Accessing an
> uninitialized POD is undefined behavior, and if you can't access
> an object, how can you say it exists?


At least in C, "access" includes both reading and modifying.
You can certainly modify an uninitialized POD object, something
you couldn't do if it didn't exist.

If you mean the lifetime of the object, why wouldn't it be the lifetime
defined in 3.8? If you mean the lifetime of the class, I'm not sure
what that would mean.

[...]

--
Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Joshua Maurice
Guest
Posts: n/a
 
      01-25-2011
On Jan 25, 11:59*am, Keith Thompson <ks...@mib.org> wrote:
> James Kanze <james.ka...@gmail.com> writes:
> > On Jan 24, 11:44 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:

> [...]
> >> We need to solve a couple of basic problems. The most important and
> >> basic is: when does the lifetime of a POD class even begin?

>
> Do you mean the lifetime of a POD *object*?


Yes. Of course. Sorry.

> > That's a good question: do PODs have lifetime? *I'd argue yes,
> > but it's not the lifetime defined in §3.8. *Accessing an
> > uninitialized POD is undefined behavior, and if you can't access
> > an object, how can you say it exists?

>
> At least in C, "access" includes both reading and modifying.
> You can certainly modify an uninitialized POD object, something
> you couldn't do if it didn't exist.
>
> If you mean the lifetime of the object, why wouldn't it be the lifetime
> defined in 3.8? *If you mean the lifetime of the class, I'm not sure
> what that would mean.


I think James was referring to how the lifetime rules for POD objects
are broken in C++. It says the lifetime of a POD object begins as soon
as memory of sufficient size and alignment is allocated, which is
absurd, because that would imply quite a large number of complete
objects of completely different types coexisting in the same piece of
memory for every piece of memory.

I'm not sure of the rules for C. Again, can you answer my questions
else-thread in the example which attempts to distinguish between the
following?
typedef struct T1 { int x; int y; } T1;
typedef struct T2 { int x; int y; } T2;

I think I'll take James's advice and take this to comp.std.c.
Hopefully they're more talkative than comp.std.c++.
 
Reply With Quote
 
Johannes Schaub (litb)
Guest
Posts: n/a
 
      01-25-2011
Joshua Maurice wrote:

> On Jan 25, 11:59 am, Keith Thompson <ks...@mib.org> wrote:
>> James Kanze <james.ka...@gmail.com> writes:
>> > On Jan 24, 11:44 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:

>> [...]
>> >> We need to solve a couple of basic problems. The most important and
>> >> basic is: when does the lifetime of a POD class even begin?

>>
>> Do you mean the lifetime of a POD *object*?

>
> Yes. Of course. Sorry.
>
>> > That's a good question: do PODs have lifetime? I'd argue yes,
>> > but it's not the lifetime defined in §3.8. Accessing an
>> > uninitialized POD is undefined behavior, and if you can't access
>> > an object, how can you say it exists?

>>
>> At least in C, "access" includes both reading and modifying.
>> You can certainly modify an uninitialized POD object, something
>> you couldn't do if it didn't exist.
>>
>> If you mean the lifetime of the object, why wouldn't it be the lifetime
>> defined in 3.8? If you mean the lifetime of the class, I'm not sure
>> what that would mean.

>
> I think James was referring to how the lifetime rules for POD objects
> are broken in C++. It says the lifetime of a POD object begins as soon
> as memory of sufficient size and alignment is allocated, which is
> absurd, because that would imply quite a large number of complete
> objects of completely different types coexisting in the same piece of
> memory for every piece of memory.
>
> I'm not sure of the rules for C. Again, can you answer my questions
> else-thread in the example which attempts to distinguish between the
> following?
> typedef struct T1 { int x; int y; } T1;
> typedef struct T2 { int x; int y; } T2;
>
> I think I'll take James's advice and take this to comp.std.c.
> Hopefully they're more talkative than comp.std.c++.


T1 and T2 are different types in C. I cannot find a rule that says that
these are compatible. So since they are different types and there is no rule
saying otherwise, the are not compatible. Thus they cannot alias each other.

All of this thread was crossposted to comp.std.c. I installed a followup-to
header that posted all this to comp.lang.c++, comp.lang.c and comp.std.c.
 
Reply With Quote
 
Joshua Maurice
Guest
Posts: n/a
 
      01-25-2011
On Jan 25, 1:35*pm, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
> Joshua Maurice wrote:
> > I'm not sure of the rules for C. Again, can you answer my questions
> > else-thread in the example which attempts to distinguish between the
> > following?
> > * typedef struct T1 { int x; int y; } T1;
> > * typedef struct T2 { int x; int y; } T2;

>
> > I think I'll take James's advice and take this to comp.std.c.
> > Hopefully they're more talkative than comp.std.c++.

>
> T1 and T2 are different types in C. I cannot find a rule that says that
> these are compatible. So since they are different types and there is no rule
> saying otherwise, the are not compatible. Thus they cannot alias each other.


I can also repeat that verbatim. Can you answer the more specific
questions which I have? I can copy and paste them into a new reply, if
you want.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      01-26-2011
On 01/25/2011 04:05 PM, Joshua Maurice wrote:
> On Jan 25, 11:59�am, Keith Thompson<ks...@mib.org> wrote:

....
>> If you mean the lifetime of the object, why wouldn't it be the lifetime
>> defined in 3.8? �If you mean the lifetime of the class, I'm not sure
>> what that would mean.

>
> I think James was referring to how the lifetime rules for POD objects
> are broken in C++. It says the lifetime of a POD object begins as soon
> as memory of sufficient size and alignment is allocated, which is
> absurd, because that would imply quite a large number of complete
> objects of completely different types coexisting in the same piece of
> memory for every piece of memory.


I think it's clear from the context that this rule does not refer to
arbitrary pieces of memory, but only the particular piece of memory
allocated for that particular object, which has only that object's
specific type.
--
James Kuyper
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is the aliasing rule symmetric? Johannes Schaub (litb) C++ 68 02-06-2011 09:33 PM
Is the aliasing rule symmetric? Johannes Schaub (litb) C++ 2 01-21-2011 11:30 PM
how to add validation rule for url in the validation-rule.xml ,I added some thing like this but......... shailajabtech@gmail.com Java 0 10-12-2006 08:36 AM
Anti-aliasing GIF Images Kevin Bertman Java 4 11-29-2004 05:46 AM
LCD anti-aliasing in Java Tim Tyler Java 2 09-05-2003 09:01 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57