#c #casting
#c #Кастинг
Вопрос:
всем привет, у меня есть этот фрагмент кода:
void writer(void* param){
if(NULL == param){
return;
}
param = (param_t*)param;
...
}
это безопасный код или нет, параметр имеет тип param_t *, но мне надоело выполнять каждый раз приведение, когда я использую его в функции, у кого-нибудь есть другое элегантное решение? заранее спасибо
Ответ №1:
Это странный сбой.
Когда вы определяете функцию, вы говорите, что параметр имеет тип void*
.
Затем с помощью приведения вы явно преобразуете его в param_t*
И компилятор неявно преобразует это param_t*
в void*
с присваиванием.
Вам нужна другая переменная
void writer(void *param) {
param_t *internal_param;
if (NULL == param) return;
internal_param = param;
/* ... */
}
Ответ №2:
Вам не нужно приводить значение void * к другому типу указателя в C.
Так что просто сделайте:
void writer(void* param){
param_t *myparam;
if(NULL == param){
return;
}
myparam = param;
...
}
(Но почему вы все равно используете void * для аргумента?)
Ответ №3:
(Неявное) приведение в присваивании безопасно, даже если значение указателя равно NULL, поэтому нет необходимости откладывать его. Вы могли бы сделать это:
void writer(void* param)
{
param_t* myparam = param;
if (myparam == NULL)
return;
...
}
Комментарии:
1. Я бы просто использовал «преобразование» (возможно, с «неявным») там: «приведение» — это «явное преобразование» 🙂
Ответ №4:
Очевидное решение — избегать использования void *
и использовать param_t *
вместо этого, как в:
void writer(param_t * param)
{
if (param == NULL)
{
return;
}
...
}
Вы могли бы отказаться от нулевого теста, если знаете, что он никогда не вызывается с нулевым указателем. В качестве альтернативы вы могли бы заменить его на assert(param != NULL)
.
Комментарии:
1. Я подозреваю, что OP следует требуемой сигнатуре функции для некоторого API, например, для функции запуска потока. Таким образом, изменение типа аргумента невозможно.