передача параметра по ссылке ?
От: DoС  
Дата: 18.10.04 14:19
Оценка:
Уважаемые гуру скажите как делать лучше (быстрее,избавляло от ошибок)
должно копмилится VC7.1

// раньше я делал так
inline int TestOld(int *A)
{
    // захотел избавится от этого
    if(NULL==A) return 0;    
    return *A;
}

// получилось так
inline int TestNeed(const int &A)
{
    return A;
}

// но оказалось что если вызвать такое
int *test=NULL;
TestNeed(*test);// краш

// надо ли защищаться от подобных ошибок ?


inline int TestNew(const int &A)
{
    // получается что нужно так ?
    if(NULL==&A)return 0;
    return A;
}
... << RSDN@Home 1.1.4 @@subversion >>
Re: передача параметра по ссылке ?
От: Аноним  
Дата: 18.10.04 14:31
Оценка:
Если есть вероятность, что будет передан null-указатель, то следует использовать тип параметра "int *", так как сразу видно, что фукция ожидает такие указатели и может с ними работать. Если функция принимает параметр-ссылку, то передача null — это ошибка вызывающего, т.к. эта функция не рассчитана на такое использование. Ссылка — это тот же указатель, но обязательно инициализированный. Получение NULL-ссылок возможно, но противоречит их назначению. Код проверки
if(NULL==&A)return 0;
выглядит неестественно, хотя и работоспосбен.
Резюме:
если функция ожидает NULL-указателей, то параметром должен быть указатель
если параметр — ссылка, то функция не ожидает null-указателей и можно смело "падать" на NULL-ссылках, так как это "неправильные" ссылки, которые делают неправильный мед. В _DEBUG версии можно ASSERT поставить
Re: передача параметра по ссылке ?
От: Bell Россия  
Дата: 18.10.04 14:31
Оценка:
Здравствуйте, DoС, Вы писали:

Если ты имеешь дело с указателями, и возможна ситуация, когда указатель может быть нулевым, то без проверок не обойтись, и ничего страшного в том, как реализована TestOld, нет. Более того, пытаться в такой ситуации использовать TestNew опасно, т.к. запись
int *test=NULL;
TestNeed(*test);// краш

ведет к неопределенному поведению из-за попытки разыменовывания нулевого указателя (поэтому проверка if(NULL==&A) тебе в общем случае не поможет).

Если так хочется убрать провекру из TestOld — надо пересмотреть дизайн и/или реадизацию, чтобы исключить перелачу нулевого указателя в эту функцию.
Любите книгу — источник знаний (с) М.Горький
Re: передача параметра по ссылке ?
От: Кодт Россия  
Дата: 18.10.04 14:34
Оценка:
Здравствуйте, DoС, Вы писали:

DoС>Уважаемые гуру скажите как делать лучше (быстрее,избавляло от ошибок)


Если передача нулевого указателя в функцию — это фича, то и надо передавать указатель.
В крайнем случае, завести второй параметр — флажок.

А если нулевые указатели не должны туда попадать, то пусть будет ссылка.
Поскольку разыменование нулевого указателя — само по себе неопределённое поведение (частный случай которого — твой ASSERT в недрах библиотечной функции), можешь умыть руки.

В отладочных целях, да и из соображений чистоты, попробуй переехать на умные указатели.
В этом случае ASSERT переезжает из функции прямо в оператор разыменования, то есть туда, где причина, а не следствие беды.
template<class T>
class some_smart_ptr
{
  T* p_;
  ...
public:
  T* operator->() const { assert(p_); return p_; } // оператор доступа к членам объекта
  T& operator*() const { assert(p_); return *p_; } // оператор доступа к самому объекту
  ...
  // заметь, что можно не открывать оператор приведения к голому указателю, во избежание соблазнов
#if 0
  operator T*() const { return p_; }
#endif
  ...
};

И вообще, можно сделать умный указатель, который не принимает нулевые значения.
Перекуём баги на фичи!
Re: передача параметра по ссылке ?
От: Batiskaf Израиль http://www.mult.ru/
Дата: 18.10.04 14:35
Оценка:
Здравствуйте, DoС, Вы писали:

DoС>Уважаемые гуру скажите как делать лучше (быстрее,избавляло от ошибок)

DoС>должно копмилится VC7.1

DoС>
DoС>// раньше я делал так
DoС>inline int TestOld(int *A)
DoС>{
DoС>    // захотел избавится от этого
DoС>    if(NULL==A) return 0;    
DoС>    return *A;
DoС>}

DoС>// получилось так
DoС>inline int TestNeed(const int &A)
DoС>{
DoС>    return A;
DoС>}

DoС>// но оказалось что если вызвать такое
DoС>int *test=NULL;
DoС>TestNeed(*test);// краш

DoС>// надо ли защищаться от подобных ошибок ?

а нужно ли защищаться от подобных ошибок:


[ccode]
char* str = NULL;
char c = str[0];
c = *str;




DoС>inline int TestNew(const int &A)

DoС>{
DoС> // получается что нужно так ?
DoС> if(NULL==&A)return 0;
DoС> return A;
DoС>}
DoС>[/ccode]

нет, не получается, ссылки тут не причем. Если ты пользуешься ссылкой, то зачем тогда строить указатель ( test ). пусть это будет автоматическая переменная, ссылку на которую ты с успехом передашь.
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[2]: передача параметра по ссылке ?
От: Bell Россия  
Дата: 18.10.04 14:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Получение NULL-ссылок возможно, но противоречит их назначению. Код проверки

А>if(NULL==&A)return 0;
А>выглядит неестественно, хотя и работоспосбен.

Неверно. Получение NULL-ссылок — это неопределенное поведение, поскольку требует разыменовывания нудевого указателя.
Любите книгу — источник знаний (с) М.Горький
Re: передача параметра по ссылке ?
От: jazzer Россия Skype: enerjazzer
Дата: 18.10.04 14:50
Оценка:
Здравствуйте, DoС, Вы писали:

DoС>Уважаемые гуру скажите как делать лучше (быстрее,избавляло от ошибок)

от ошибок в ДНК не избавишься

DoС>// но оказалось что если вызвать такое

DoС>int *test=NULL;
DoС>TestNeed(*test);// краш

DoС>// надо ли защищаться от подобных ошибок ?


нет, не нужно
ибо ссылка может быть привязана только к объекту, объектов же с нулевым адресом не бывает.
и вся тяжесть ответственности в данном случае лежит на вызывающей стороне.
а уж разывменование нулевого указателя — здесь вообще диск будет отформатирован раньше, чем управление будет передано в твою функцию.

И еще посмотри, например, на стандартные функции работы со строками типа strlen: в них нельзя передавать нулевой указатель, но они ничего не проверяют — это записано в документации
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: передача параметра по ссылке ?
От: DoС  
Дата: 19.10.04 11:57
Оценка:
Всем огромное спасибо .
... << RSDN@Home 1.1.4 @@subversion >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.