This is the mail archive of the gcc-patches@gcc.gnu.org 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



Daniel Berlin wrote:
but if there's
no exemption for character pointers in that case, there should be, at
least in GNU C, where we assume unsegmented memory.

If you're going to make a general extension for GNU C where memory is unsegmented, you'll kill a lot of optimisations. Such an extension would mean that any pointer could be used to access any suitably typed data value.


On 10/05/2005, at 11:07 AM, Mark Mitchell wrote:

Daniel Berlin wrote:


I had this discussion at Apple with Geoff Keating and Mike Stump. When I left, they were on board with this. I would not have taken the time to do this if I thought I was bending the language. A never talked to Matt about this.


I'm sure Geoff and Mike will share their reasoning.


The dodgy bit to me seems to be the pointer arithmetic, since arithmetic on pointers is constrained to take place within a single array.

However, C99 6.3.2.3/8 says:

"When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object." So, that does say that we can portably implement memcpy by casting the object address to "const unsigned char *" and then stepping through the object.

Pedantically, this doesn't permit any other operation other than increments; it doesn't say that you can add two, or decrement after you increment, but disallowing those operations would be silly. I don't this it pays to read standards *that* pedantically.

That's still not quite enough to support validity of the code you posted, in that you were taking the address of a field in the object, not the entire object. But I think it is enough to support validity of:

  struct S {
    int i;
    int j;
  };

  void f(int *p) {
    p = (int *)((char *)p - offsetof (struct S, j))
    *p = 3;
  }

  void g() {
    S s;
    f ((int *) ((char*) &s + offsetof (struct S, j)));
  }

So, I think that the argument for invalidity has to hinge on the fact that "(int*)((char*) &s + offsetof (struct S, j)))" is different from "&s.j", even though the standard says those two expressions have the same type and the same value.


When you write '&(s.i)' (parentheses added for clarity), 6.5.3.2 paragraph 3 says "the result is a pointer to the object or function designated by its operand", and the operand is 's.i', and s.i is only sizeof(int) bytes long, so 6.3.2.3 only specifies the behaviour if you increment '(char *)&(s.i)' up to sizeof(int) times. (I agree that you can add or subtract, so long as you stay between '(char *)& (s.i)' and '(char *)&(s.i) + sizeof(s.i)' inclusive.)

I can't find any part of the standard where it says that you can to cast a 'char *' to 'int *' and dereference or otherwise process the result if the 'char *' wasn't the result of converting an 'int *'. So in this case we're implementing an undocumented GCC extension. I don't think it's unreasonable to allow this, and I would define it as follows:

A pointer to an object which has been cast to a pointer to a character type and then incremented so that it points to the lowest addressed byte of a member object of the first object may be cast to the type of the member object to produce a pointer to that object.

(Look at 6.2.5 paragraph 20 to see what a 'member object' is.)

This would mean that in fact '&s.j' is the same as '(int*)((char*) &s + offsetof (struct S, j)))'. I think that makes sense. However, it does not make the operations in 'f' above defined. I think that makes sense too.

Attachment: smime.p7s
Description: S/MIME cryptographic signature


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