Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
623 views
in Technique[技术] by (71.8m points)

c - less than comparison for void pointers

I want to compare two void pointers like this:

void foo(void* p1, void* p2) {

  if (p1 < p2) {
    void *tmp = p1;
    p1 = p2;
    p2 = tmp;
  }

  // do something with p1 and p2.
}

Is this correct according to the standard? I mean is the comparison of void pointers a well-defined behaviour?

I'd appreciate if someone can point me to the C standard where this is documented.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As Drew McGowen pointed out in a comment, but I'll post the quote here:

6.5.8 Relational operators

5 When two pointers are compared, the result depends on the relative locations in the address space of the objects pointed to. If two pointers to object types both point to the same object, or both point one past the last element of the same array object, they compare equal. If the objects pointed to are members of the same aggregate object, pointers to structure members declared later compare greater than pointers to members declared earlier in the structure, and pointers to array elements with larger subscript values compare greater than pointers to elements of the same array with lower subscript values. All pointers to members of the same union object compare equal. If the expression P points to an element of an array object and the expression Q points to the last element of the same array object, the pointer expression Q+1 compares greater than P. In all other cases, the behavior is undefined.

That's from the C11 standard. C99 is the same.

From C++11, it's more or less the same. Some tweaks about pointer conversions, I can paste it all if you want. More importantly, the behaviour is Unspecified (as Chris pointed out above).

Note that Undefined Behaviour is lethal. If you compare two unrelated pointers, your machine may catch fire, launch nuclear missiles, make demons fly out of your nose, etc.

Unspecified Behaviour has to do something vaguely reasonable. The compiler doesn't have to document it, or even do the same thing for two different programs, but it can't blow up the world. Your program is still considered valid.

So in your particular case, compiling as C, the user could cause Undefined Behaviour depending on what they pass to the function. This seems pretty dangerous.

Also, contrary to my comment on the question, you cannot just use != on two arbitrary void*s: C11

6.5.9 Equality operators

2 One of the following shall hold:

— both operands have arithmetic type;

— both operands are pointers to qualified or unqualified versions of compatible types;

— one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void; or

— one operand is a pointer and the other is a null pointer constant.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...