简体   繁体   中英

C compare two pointers greater than if one is null

If I compare two pointers in CI am aware of C 6.5.8/5 which says:

pointers to structure members declared later compare greater than pointers to members declared earlier in the structure

That is fine but what if one of the pointers is NULL ? I know I can do foo != NULL but for example is this against the standard:

char *bar = NULL;
char *foo = "foo";
if(foo > bar) { function(); }

The section doesn't specifically address NULL in the case of greater than which is why I'm confused. Also if you could tell me if it applies to C89 as well as C99.

To clarify, this has nothing to do with structures that is just the part of the standard I was quoting. The code is very similar to what I describe above. I have some pointers to an array and one of those pointers may be null therefore I'd like to know if it's ok to compare using greater than.

Your example is indeed undefined. As explained in C11, 6.5.8., p5 , every rule mandates that pointers point to the same object or one past that object.

So, two pointers may be compared using relational operators: <, >, <=, >= , only if they point to the same object or one past that object. In all other cases:

6.5.8. Relational operators,

  1. . In all other cases, the behavior is undefined.

Pointer with the value NULL, a null pointer, doesn't point to an object. This is explained in:

6.3.2.3 Pointers

  1. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.

The C99 standard says:

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.

The key here is in same object :

struct {
  int a; // structrure members
  int b;
} some_struct;

// so pointers to structure members:
&(some_struct.b) > &(some_struct.a)

The same applies for arrays:

char arr[128];
&(arr[100]) > &(arr[1])

If a pointer is NULL then it is most probably not pointing to a member of the same data structure, unless you're programming the BIOS (and even then it's against the standard, since the null pointer is guaranteed to not point inside any object), so the comparison becomes kinda useless

pointers to structure members declared later compare greater than pointers to members declared earlier in the structure

The quote only describes member variables inside a struct. For example:

struct A {
  int a;
  int b;
};

Then any instance of A has it's address of a smaller than b.

In other words, if someone write a statement like the followings:

 A instanceA;
 int* aa = &(instanceA.a);
 int* ab = &(instanceA.b);

then it is guaranteed that ab > aa as member variable b is defined later than a.

That section of code is talking about:

#include <stdio.h>

struct things {
    int blah;
    int laterz;
};   

struct things t;

int main ( void ) {

    int * a = &t.blah;
    int * b = &t.laterz;

    printf("%p < %p\n", (void *)a, (void *)b);
    return 0;
}

A pointer to laterz is greater than one to blah.

The specification also says that you can only compare two related pointers using anything else than equality or inequality.

So if you have two pointers that both point to different places in the same buffer then you can compare them using the greater or lesser than operators., not other wise.

Example

char buffer1[] = "foobar";
char buffer2[] = "some other text";
char *ptr1 = buffer1 + 3;
char *ptr2 = buffer2;

With the above, you can compare buffer1 and ptr1 using < and > . You can't do that with ptr1 and ptr2 , only use the == or != operators.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM