[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v6 1/4] xen: introduce SYMBOL
>>> On 15.01.19 at 21:03, <Stewart.Hildebrand@xxxxxxxxxxxxxxx> wrote: > On Tuesday, January 15, 2019 3:21 AM, Jan Beulich wrote: >> The thing that I don't understand though is how the undefined >> behavior (if there really is any) goes away: Even if you compare >> the contents of the variables instead of the original (perhaps >> casted) pointers, in the end you still compare what C would >> consider pointers to different objects. It's merely a different >> way of hiding that fact from C. Undefined behavior would imo >> go away only if those comparisons/subtractions didn't happen >> in C anymore. IOW - see my .startof.() / .sizeof.() proposal. > > No, the C standard provides us a guarantee. > > To quote the ISO/IEC 9899 C99 standard regarding the subtract operator: >> For subtraction, one of the following shall hold: >> - both operands have arithmetic type; >> - both operands are pointers to qualified or unqualified versions of >> compatible object types; or >> - the left operand is a pointer to an object type and the right operand >> has integer type. >> >> If both operands have arithmetic type, the usual arithmetic conversions >> are performed on them. >> >> When an expression that has integer type is added to or subtracted from >> a pointer ... 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; otherwise, >> the behavior is undefined. > > Here, "arithmetic type" is either integer type or floating point type (but > NOT pointer type). > > There is similar language for the equality comparison operator that > Stefano quoted earlier in the thread. > > My interpretation of the standard is: > Subtract/compare operations where one or both operands are pointer types > are potentially subject to the "pointers to different objects" issue, and > the compiler is free to make that determination by any means available. > Subtract/compare operations where both operands are integer types are well > defined in the C standard, and, per the C standard, are NOT subject to the > "pointers to different objects" issue. If the compiler starts to consider > integer types being "pointers to different objects" then the compiler > clearly does not adhere to the C standard. The compiler may look through > *pointer type* casts, but if it started to look through *integer type* > casts, we would have good reason to complain to the GCC mailing list. All fine. Yet wasn't it you who suggested that a future, very smart compiler could "look through" casts and even inline assembly? Of course subtraction and comparison of arithmetic types is well defined. The question is whether this also holds for pointers casted to such types. Let's not forget that in the abstract case, casting a pointer to an integral type may be lossy, and subtraction of two such casted values may not represent what you'd expect it to be. The best way to demonstrate this are the historic large and huge memory models on 16-bit x86. Pointers are comprised of a segment/selector and an offset there. When the former is a segment (real or vm86 modes), conversion can be done such that the difference is "meaningful" in our sense. When it's a selector, otoh, I can't think of a conversion that would allow meaningful comparison / subtraction. Even worse, two entirely distinct pointers (different selectors referring to descriptors with different base addresses) may point at the same object. Luckily we don't have to consider such obscure environments (and hence we can make certain implications), but the C standard has to. In any event - since intermediate variables merely hide the casting from the compiler, but they don't remove the casts, the solution involving casts is better imo, for incurring less overhead. Since casts, as discussed before, are not meaningfully more helpful than hiding the origin object from the compiler, retaining pointer types is (to me) further preferable over the casting to integer types, not the least because of the general risk involved with type changing casts (for the last so many years I've been objecting to unnecessary casts in all of the reviews I've done for this very reason). > Just to reiterate, MISRA C says: don't subtract/compare *pointer types* > pointing to different objects, otherwise it's "undefined behavior" except > in one irrelevant corner case (I'm paraphrasing since the actual text is > copyrighted). If the operands are both integer types (not pointer types), > we don't risk violating the MISRA rules pertaining to pointer types. I continue to have two problems with this: For one this doesn't talk about pointers cast to integers. And then the term "different object" is fuzzy as soon as we're talking about things coming from outside of C land. And taking into consideration language extensions (are such inside or outside of C land?) like weak aliases, things become even more fuzzy. gcc looks to be prepared for such - just look at the generated code for extern int ei1, ei2; int i1 = 1, i2 = 2; extern int ai1[], ai2[]; int __attribute__((weak)) wi1 = 1; int __attribute__((weak)) wi2 = 2; int test1(void) { return &ei1 == &ei2; } int test2(void) { return ai1 == ai2; } int test3(void) { return &i1 == &i2; } int test4(void) { return &wi1 == &wi2; } And there are further issues of fuzziness - take for example the folding of literals. Are two distinct instances of identical (string) literals one object, or two different ones? I've searched the spec, but couldn't spot any statement. Yet the "if and only if" in the wording of the equality operator descriptions requires this to be well defined. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |