This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH]: Fix PR tree-optimization/21407

On May 11, 2005, at 6:21 PM, Geoff Keating wrote:
One implicit thing that you haven't said is "and then execution continues as specified in the rest of the standard". The problem is that in this case, that's not a complete specification

A complete specification isn't required, only enough constraints to mandate that the right thing happen.

and in fact will in this example quickly lead to undefined behaviour again.

This is in dispute of course.

[basic.compound] para 3 says "The value representation of pointer types is implementation-defined."

This is immaterial and means nothing. Well, technically, it means you cannot printf %x and intuit meaning from what you see... and that is about it, since we aren't doing that, this is irrelevant.

So just saying "the bit patterns are the same" could produce any result.

Only so far as the rest of the standard doesn't mandate a particular case, in this case, i'd claim it does, therefore, it cannot.

So let's say that you actually define the result as having a value of the same address as the original pointer.

It is, by definition.

OK, so now we have two pointers, different types, same address. Let's assume that there is an object of type 'int' at that address, which the original pointer pointed to. Now we have a pointer to 'char' at the same address. Let's assume no object of type 'char' has been created at that address: there's an exhaustive list of the ways that objects are created in [intro.object], and none of them has happened.

Odd, in his code I see:

I i;

and accordingly, the standard says:

An object is created by a definition (_basic.def_)

I don't think this gets any clearer than that. In case you missed why a and b are also objects and are created by that same line:

2 Objects can contain other objects, called sub-objects. A sub-object
can be a member sub-object (_class.mem_), a base class sub- object
(clause _class.derived_), or an array element. An object that is not
a sub-object of any other object is called a complete object.

again, couldn't be clearer. As for the char, it exists by definition:

The object representation of an object of type T is the sequence of N
unsigned char objects taken up by the object of type T, where N equals

One cannot have a complete object of type T, without the sequence of N unsigned char objects.

[basic.compound] para 3 says that "If an object of type T is located at an address A, a pointer of type cv T* whose value is the address A is said to point to that object, regardless of how the value was obtained." It doesn't say anything about what happens if there isn't an object of the right type there.

But there is. There is a character (by definition) and there is an int, either may be accessed.

So now you have to fill in that blank, or be back at undefined behaviour again: does this pointer point to an object? What object?

Why guess, just read [] for the rules. I don't find it inaccessible. In this case, the int comes into being:

1 The lifetime of an object is a runtime property of  the  object.   The
  lifetime of an object of type T begins when:

--storage with the proper alignment and size for type T is obtained,

and ends:

The lifetime of an object of type T ends when:

--the storage which the object occupies is reused or released.

failure to reuse or release, means it doesn't end, save program termination:

The storage for these objects shall
last for the duration of the program (_basic.start.init_,

You can't find those answers by reading the standard;

I can. Anyone trained to read it should be able to.

The C++ standard says this in almost as many words, [basic.compound] p3. (C is very different, and I don't think that statement is true in C.)

C++ is meant to be our understanding of what C says, really, honest. (1) Ok, this is true only some of the time, but, generally speaking, it is true, but don't bother pointing out the deviations, I know of them already.

I think that [expr.add] paragraph 5 is pretty much a statement that sometimes, when you add and subtract things from pointers, it can fail: "If [blah blah], the evaluation shall not produce an overflow; otherwise, the behavior is undefined."

No; if both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow! It is mandated to never fail in that case.

It talks about elements of an array object. And that takes us back to the start, which is "what object, if any, does this pointer point to?" Is it an array object? How long is it?

The char pointer is a pointer to the object's representation, really. That is defined to be:

4 The object representation of an object of type T is the sequence of N
unsigned char objects taken up by the object of type T, where N equals

No amount of changing of the char pointer, changes the type, char, nor the size, N (sizeof(T)), nor the location of the object, nor the lifetime of the char objects, nor the lifetime of the compete object (T).

Now, before you ask, how did you come to that conclusion:

2 An rvalue of type "pointer to cv T," where T is an object type, can be
converted to an rvalue of type "pointer to cv void." The result of
converting a "pointer to cv T" to a "pointer to cv void" points to the
start of the storage location where the object of type T resides, as
if the object is a most derived object (_intro.object_) of type T
(that is, not a base class subobject).

and, before you point out, that has nothing to do with the char *:

cv-qualified or cv-unqualified (_basic.type.qualifier_) void* shall
have the same representation and alignment requirements as a cv- quali-
fied or cv-unqualified char*.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]