Нет, не обязательно безопасно передавать char**
там, где ожидается void**
(что на самом деле является параметром функции void*[]
). Тот факт, что компилятор заставляет вас выполнять явное приведение типов, является намеком на это.
На практике, скорее всего, все будет хорошо. Однако, строго говоря, у вас обычно нет гарантии, что sizeof (T*) == sizeof (U*)
для различных типов T
и U
. (Например, вы можете представить гипотетическую систему, в которой sizeof (int*) < sizeof (char*)
, потому что указатели на int
выровнены и, следовательно, не нужно хранить младшие значащие биты.) Следовательно, ваша функция swap
может индексировать массив v
, используя неправильные смещения.
Также см. вопрос 4.9 в часто задаваемых вопросах comp.lang.c: Могу ли я указать формальный параметр введите void **
и сделайте что-нибудь подобное?
Чтобы безопасно вызвать swap
, вы должны сделать что-то вроде:
void* temp[] = { &s[0], &s[1] };
swap(temp, 0, 1);
хотя это поменяло бы местами элементы temp
, а не s
.
Если вы создаете swap
, в общем случае вы должны сделать так, чтобы такая функция принимала аргумент void*
(вместо void**
) и аргумент size_t
, определяющий размер каждого элемента. Затем ваша функция может безопасно преобразовать void*
в char*
и поменять местами отдельные байты:
void swap(void* p, size_t elementSize, size_t i, size_t j)
{
char* item1 = p;
char* item2 = p;
item1 += i * elementSize;
item2 += j * elementSize;
while (elementSize-- > 0) {
char temp = *item1;
*item1 = *item2;
*item2 = temp;
item1++;
item2++;
}
}
Изменить: также см. этот ответ StackOverflow на аналогичный вопрос.
person
jamesdlin
schedule
15.05.2013
char*
отличается от размераint*
. - person jamesdlin   schedule 15.05.2013