Как правильно вернуть не нулевой указатель
Я использую внешнюю библиотеку C в моей программе C++, и библиотека использует функцию обратного вызова, которая должна возвращать void*. Библиотека проверяет, не является ли возвращаемое значение NULL, что означает успех.
Итак, что является лучшим способом, чтобы сказать ему, что все нормально?
Я использую:
return reinterpret_cast<void*>(1);
Но это выглядит уродливо...
Edit: спасибо за ответ, я останусь с этим:
static int success;
return &success;
5 ответов:
static int dummy; return &dummy;Строго говоря,
static, вероятно, не требуется, но кажется немного неловким возвращать указатель на локальный объект, который выходит за пределы области видимости.EDIT: обратите внимание на комментарий @sharptooth. Строго говоря,
staticтребуется .
Использование
reinterpret_castнастолько чисто, насколько это возможно. Проблема в том, что создание таких указателей из литераловintприводит к неопределенному поведению - стандарт запрещает использование указателей, которые не являются нулевыми и не указывают на правильно выделенные объекты. Стандартный способ-это иметь некоторую переменную (возможно, наиболее удобной будет переменная области видимости файла) и возвращать ее адрес.
Я бы, наверное, написал что-то вроде:
return const_cast<void*>(""); // non-null pointer, referand doesn't matterВозможно, функция обратного вызова имеет входной указатель, гарантирующий, что он не будет равен нулю. Если так, то вы можете вернуть это.
reinterpret_cast<void*>(1)предполагается, что будет выглядеть уродливо, потому что это не гарантированно сработает. Большинство архитектур не возражают против этого, но
- стандарт на самом деле не гарантирует, что вы можете использовать значение указателя, которое не является адресом какого-либо объекта (или нулевым указателем, или одноразовым массив).
- стандарт не гарантирует, что
reinterpret_cast<void*>(1)не является нулевым указателем, это определяется реализацией.Я сомневаюсь, что действительно существует реализация, в которой ваша функция возвращает null случайно, но есть позволено быть. Представьте себе гипотетическую реализацию, в которой собственная адресация процессора является 4-битной, а не 8-битной. Конечно, разработчик все равно выберет
CHAR_BIT == 8, и все указатели в C++ будут выровнены по 8 битам. Тогда реализация могла бы законно и достаточно разумно сопоставить от указателей к целым числам, оставив битовый шаблон неизменным, и от целых чисел к указателям, обнулив последний бит. В качестве альтернативы он может сдвигать вправо и влево на 1 бит. Стандарт требует, чтобы указатель -> integer -> pointer восстанавливал исходное значение, но не требует, чтобы целочисленный -> указатель -> integer это делал.
Как насчет
return this;Как простой способ вернуть допустимый указатель, который гарантированно будет ненулевым?
На моем месте я бы использовал:
return (void*)1;Просто и красиво.
Я предпочитаю значение 1 (Как вы использовали в вопросе) любому другому значению, потому что другие значения могут быть интерпретированы каким-то образом (что не очень хорошо). Если все, что вы хотите,-это вернуть ненулевое значение (ненулевой указатель), то лучше использовать значение, из которого ничего особенного извлечь нельзя.
Comments