【C言語】
ポインタは負になるか?
(void *)-1の使い方

warning: ordered comparison of pointer with integer zero

warning: ordered comparison between pointer and zero (‘void *’ and ‘int’) is an extension

警告:整数の0とのポインタの比較
[-Wextra]
[-Wpedantic]


■この記事の概要

この記事では、C言語におけるポインタと整数値の比較の問題を解説しています。特に、ポインタは負の値を取らないため、(void *)-1との比較が必要な状況や、ポインタオーバーフローの未定義動作を具体例で説明。安全なポインタ操作のためのベストプラクティスを示しています。


■ポインタは負値にならない

#include    <stdio.h>
#include    <sys/shm.h>
int main(void) {
    void    *ptr = shmat(0,0,0);
    if(ptr < 0){//成立する事はない
        perror("shmat");
    }
}

成功時ポインタを返し
失敗時-1を返す関数の失敗判定でポインタは0より小さくならないので、このif文が成立する事はありません。


■(void *)-1と比較すると良い

#include    <stdio.h>
#include    <sys/shm.h>
int main(void) {
    void    *ptr = shmat(0,0,0);
    if(ptr == (void *)-1){//成立する事がある
        perror("shmat");
    }
}

成功時ポインタを返し
失敗時-1を返す関数の失敗判定はこのように記述してください。


(warning) Comparison is wrong.
Result of ‘p+1’ can’t be 0 unless there is pointer overflow,
and pointer overflow is undefined behaviour.

比較が正しくありません。
ポインタのオーバーフローがない限り、
‘p+1’の結果はNULLにはなりえず、
ポインタのオーバーフローは未定義の動作です[(warning)pointerAdditionResultNotNull]

■ポインタのオーバーフローは未定義動作になる

#include    <stdio.h>
int main(void) 
{
    for(char *p = "string"; p[0] != '\0';p++){
        if((p + 1) == NULL){    //★ダメ  
            printf("THEN\n");
        } else {
            printf("ELSE\n");
        }
    }    
}

有効なポインタ に定数を加算してもNULLポインタにはなりません。

例外として、ポインタがオーバーフローするとNULLポインタに
なるかもしれませんが
ポインタのオーバーフローは未定義動作なので
一切の動作保証がありません。

参考:

MSC15-C. 未定義の動作に依存しない