Сравнение указателя с -1 - PullRequest
1 голос
/ 01 декабря 2011

У меня довольно философская проблема с проверкой вывода функции shmat.Делая это:

void * addr = shmat(shmid, NULL, 0);
if( addr == -1)
{
    perror("Uncool stuff");
}

дает мне:

warning: comparison between pointer and integer

И это совершенно нормально.К сожалению, руководство говорит:

Upon success, shmat() returns the address where the segment is attached; 
otherwise, -1 is returned and errno is set to indicate the error.

Это довольно стандартное поведение, но как мне с этим справиться?if (addr == (void *) -1) правильно?Я прочитал этот вопрос и теперь я не совсем уверен, если бы он был на 100% правильным на каждой возможной платформе-бла-бла-бла ;-) Я не нашел других надежных источниковпо этому вопросу.

Я считаю, что спрашивать о подписанности указателей - ошибка, потому что указатели не являются числами.Но в таком случае я больше не уверен ...

Редактировать : эта проблема приводит нас к другому вопросу: char *addr = (char*)shmat(...) правильно?Согласно полученным ответам, это так, но если мы не примем во внимание ни слова, и т. Д., И т. Д. Да, возможно, я теряю связь с реальностью здесь, но мне любопытно, есть ли THE собственноспособ.

Ответы [ 3 ]

4 голосов
/ 01 декабря 2011

В документации конкретно говорится, что shmat возвращает (void*)-1 в случае ошибки, так что это то, с чем вы должны сравнить результат. Возможно, вы просматриваете более старую версию документации. Это что-то вроде хака, но это должно быть хорошо в любых POSIX-совместимых системах (это делает предположения, которые не гарантированы стандартом C). Преобразование возвращенного указателя в целочисленный тип с последующим сравнением с -1 может работать или не работать; Например, учтите, что int и void* могут иметь разные размеры.

Не пытайтесь проверить errno без предварительной проверки возвращенного значения. В общем случае функции могут устанавливать errno в ненулевое значение, даже если они успешны. Всегда проверяйте возвращаемое значение для обнаружения сбоя, затем вы можете проверить errno, чтобы определить тип сбоя. И если вы собираетесь проверить errno, обязательно установите его в 0 перед вызовом. (Я не уверен, что это строго необходимо в этом случае, но это хорошая практика.)

1 голос
/ 01 декабря 2011

IMO, этот тест должен работать почти во всех случаях if (addr == (void*)-1 ...

Если вы действительно хотите обойти проблему, выполните #include <errno.h> ... errno = 0; void * addr = shmat(shmid, NULL, 0); if (errno != 0) ... IOW, используя errno для обнаружения ошибки, а не возвращаемое значение из shmat.

(в моих модульных тестах у меня был случай для моих предположений; запуск их на новой платформе помог бы вам обнаружить ошибку, вызванную неожиданным поведением на этой платформе.)

1 голос
/ 01 декабря 2011

да, это правильно, но безобразно.

Чтобы он мог вернуть -1, он должен выполнять такой же тип приведения, поэтому он должен работать на большинстве платформ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...