Переименуйте
header..blade.php
в
header.blade.php
На ваш взгляд есть две точки (..)!
void**
допустимо, но на основе Вашего сообщения об ошибке, вероятно, необходимо явно бросить аргумент следующим образом:
mystruct **var1;
x = myfunc ((void**) var1);
Поэтому myfunc
функция ожидает void**
ввести. В то время как void*
может быть неявно брошен к любому другому указателю, который не является так для двойного указателя - необходимо явно бросить его.
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);
Существует причина, от которой не может автоматически бросить компилятор mystruct**
кому: void**
.
Рассмотрите следующий код:
void stupid(struct mystruct **a, struct myotherstruct **b)
{
void **x = (void **)a;
*x = *b;
}
Компилятор не будет жаловаться на неявный бросок от myotherstruct*
кому: void*
в *x = *b
строка, даже при том, что та строка пытается поместить указатель на a myotherstruct
в месте, где только указатели на mystruct
должен быть помещен.
Ошибка находится на самом деле в предыдущей строке, которая преобразовывает "указатель на место где указатели на mystruct
может быть помещен" в "указатель на место, куда указатели на что-либо могут быть помещены". Это - причина нет никакого неявного броска. Конечно, при использовании явного броска компилятор предполагает, что Вы знаете то, что Вы делаете.
Этот вопрос немного сбивает с толку. Но да, void **
конечно, легальный и допустимый C и означает "указатель на указатель на void
"как ожидалось.
Я не уверен в Вашем примере вызова, аргументы ("mystruct ** var1") не имеют смысла. Если var1
имеет тип mystruct **
, вызов должен просто читать a = func(var1);
, это могло бы быть опечаткой.
Кастинг должен работать, но необходимо бросить к void **
, начиная с именно это функция ожидает.
Столь грязный, как это может быть похожим: иногда Вы не можете решить проблему, не используя пусто **.
Да, void **
совершенно приемлемо и довольно полезен при определенных обстоятельствах. Также рассмотрите это, учитывая объявление void **foo
и void *bar
, компилятор будет знать размер объекта, на который указывает нечто (это указывает на указатель, и все указатели являются тем же размером за исключением нескольких древних платформ, которые Вы не должны волновать по поводу), но это не будет знать размера объекта, на который указывает панель (это могло указать на объект любого размера). Можно поэтому безопасно выполнить адресную арифметику с указателями на void **
указатели, но не на void *
указатели. Необходимо бросить их к чему-то еще сначала, как a char *
. GCC позволит Вам симулировать это void *
и char *
эквивалентны, каждый указывающий на объект единственный байт в размере, но это нестандартно и непортативно.