Пустой ** приемлемый тип в ANSI-C?

Переименуйте

header..blade.php

в

header.blade.php

На ваш взгляд есть две точки (..)!

7
задан Jens 27 December 2012 в 20:14
поделиться

6 ответов

void** допустимо, но на основе Вашего сообщения об ошибке, вероятно, необходимо явно бросить аргумент следующим образом:

mystruct **var1;
x = myfunc ((void**) var1);

Поэтому myfunc функция ожидает void** ввести. В то время как void* может быть неявно брошен к любому другому указателю, который не является так для двойного указателя - необходимо явно бросить его.

8
ответ дан 6 December 2019 в 05:39
поделиться

comp.lang.c FAQ решает эту проблему подробно рассматриваемые 4.9. Короче говоря, они говорят, что это не строго портативно для кастинга произвольного от указателя к указателю на a void **; они продолжают объяснять, что "код как это может работать и иногда рекомендуется, но он полагается на все типы указателей, имеющие то же внутреннее представление (который распространен, но не универсален)". Они продолжают объяснять это "любой void ** оцените Вас, игра с должна быть адресом фактического void * оцените где-нибудь; броски как (void **)&dp, хотя они могут закрыть компилятор, являются непортативными (и даже может не сделать то, что Вы хотите)."

Так, можно безопасно/портативно достигнуть желаемого поведения с кодом как:

some_type *var1 = foo();
void *tmp_void_ptr = (void *)var1;
myfunc(&tmp_void_ptr);
22
ответ дан 6 December 2019 в 05:39
поделиться

Существует причина, от которой не может автоматически бросить компилятор mystruct** кому: void**.

Рассмотрите следующий код:

void stupid(struct mystruct **a, struct myotherstruct **b)
{
    void **x = (void **)a;
    *x = *b;
}

Компилятор не будет жаловаться на неявный бросок от myotherstruct* кому: void* в *x = *b строка, даже при том, что та строка пытается поместить указатель на a myotherstruct в месте, где только указатели на mystruct должен быть помещен.

Ошибка находится на самом деле в предыдущей строке, которая преобразовывает "указатель на место где указатели на mystruct может быть помещен" в "указатель на место, куда указатели на что-либо могут быть помещены". Это - причина нет никакого неявного броска. Конечно, при использовании явного броска компилятор предполагает, что Вы знаете то, что Вы делаете.

3
ответ дан 6 December 2019 в 05:39
поделиться

Этот вопрос немного сбивает с толку. Но да, void ** конечно, легальный и допустимый C и означает "указатель на указатель на void"как ожидалось.

Я не уверен в Вашем примере вызова, аргументы ("mystruct ** var1") не имеют смысла. Если var1 имеет тип mystruct **, вызов должен просто читать a = func(var1);, это могло бы быть опечаткой.

Кастинг должен работать, но необходимо бросить к void **, начиная с именно это функция ожидает.

1
ответ дан 6 December 2019 в 05:39
поделиться

Столь грязный, как это может быть похожим: иногда Вы не можете решить проблему, не используя пусто **.

0
ответ дан 6 December 2019 в 05:39
поделиться

Да, void ** совершенно приемлемо и довольно полезен при определенных обстоятельствах. Также рассмотрите это, учитывая объявление void **foo и void *bar, компилятор будет знать размер объекта, на который указывает нечто (это указывает на указатель, и все указатели являются тем же размером за исключением нескольких древних платформ, которые Вы не должны волновать по поводу), но это не будет знать размера объекта, на который указывает панель (это могло указать на объект любого размера). Можно поэтому безопасно выполнить адресную арифметику с указателями на void ** указатели, но не на void * указатели. Необходимо бросить их к чему-то еще сначала, как a char *. GCC позволит Вам симулировать это void * и char * эквивалентны, каждый указывающий на объект единственный байт в размере, но это нестандартно и непортативно.

0
ответ дан 6 December 2019 в 05:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: