Я не могу понять этого:
int main() {
int (*) (int *) = 5;
return 0;
}
Приведенное выше назначение компилируется с g ++ c ++ 11. Я знаю, что int (*) (int *)
это указатель на функцию, которая принимает (int *)
аргумент as и возвращает int, но я не понимаю, как вы могли бы приравнять его к 5. Сначала я подумал, что это функция, которая постоянно возвращает 5 (из моего недавнего обучения в F #, наверное, ха-ха), тогда я подумал вкратце, что указатель функции указывает на ячейку памяти 5, но это явно не работает, как и шестнадцатеричные значения.
Думая, что это может быть потому, что функция возвращает int, и что назначение int нормально (как-то), я также попробовал это:
int * (*) (int *) = my_ptr
где my_ptr
имеет тип int *
того же типа, что и этот второй указатель на функцию, как и в первом случае с типом int. Это не компилируется. Назначение 5 или любого другого значения int вместо my_ptr
этого также не компилируется для этого указателя на функцию.
Итак, что означает задание?
Обновление 1
У нас есть подтверждение, что это ошибка, как показано в лучшем ответе. Однако до сих пор неизвестно, что на самом деле происходит со значением, которое вы присваиваете указателю на функцию, или что происходит с присвоением. Будем очень признательны за любые (хорошие) объяснения по этому поводу! Пожалуйста, обратитесь к приведенным ниже изменениям, чтобы прояснить проблему.
Редактировать 1
Я использую gcc версии 4.8.2 (в Ubuntu 4.8.2)
Редактировать 2
На самом деле, приравнивание его ко всему работает в моем компиляторе. Работает даже приравнивание ее к переменной std :: string или имени функции, возвращающей значение типа double.
Изменить 2.1
Интересно, что если сделать его указателем функции на любую функцию, которая возвращает тип данных, который не является указателем, это позволит ей компилироваться, например
std::string (*) () = 5.6;
Но как только указатель функции находится на функции, которая возвращает какой-то указатель, он не компилируется, например, с
some_data_type ** (*) () = any_value;
источник
error: expected identifier or '(' before ')' token
int *x = 5
твоим именемx
. Сint * (*x) (int *) = 5
этим компилироваться не буду. (хотя он будет компилироваться как код C).int(*) = 5;
int(*);
Ответы:
Это ошибка в g ++.
int (*) (int *)
это имя типа.
В C ++ у вас не может быть объявления с именем типа без идентификатора.
Итак, это компилируется с g ++.
int (*) (int *) = 5;
и это также компилируется:
int (*) (int *);
но оба они недействительны.
ИЗМЕНИТЬ :
TC упоминает в комментариях ошибку bugzilla 60680 с аналогичным тестовым примером,
но она еще не утверждена. Ошибка подтверждена в bugzilla.РЕДАКТИРОВАТЬ2 :
Когда два вышеуказанных объявления находятся в области видимости файла, g ++ правильно выдает диагностику (не может выполнить диагностику в области видимости блока).
РЕДАКТИРОВАТЬ3 :
Я проверил и могу воспроизвести проблему в последней версии g ++ версии 4 (4.9.2), последней предварительной версии 5 (5.0.1 20150412) и последней экспериментальной версии 6 (6.0.0 20150412).
источник
error C2059: syntax error : ')'
int (*int_func)(int *);
что объявляет указатель на функцию с именемint_func
.int x[5];
и нетint[5] x;
Это недопустимый C ++. Помните, что, поскольку ваш конкретный компилятор компилируется, это не делает его действительным. Компиляторы, как и все сложное программное обеспечение, иногда содержат ошибки, и это одна из них.
Напротив,
clang++
жалуется:funnycast.cpp:3:11: error: expected expression int (*) (int *) = 5; ^ funnycast.cpp:3:18: error: expected '(' for function-style cast or type construction int (*) (int *) = 5; ~~~ ^ funnycast.cpp:3:19: error: expected expression int (*) (int *) = 5; ^ 3 errors generated.
Это ожидаемое поведение, поскольку строка с нарушением не является допустимой для C ++. Он претендует на присвоение (из-за
=
), но не содержит идентификатора.источник
Как указывали другие ответы, это ошибка, которая
компилируется. Разумное приближение этого утверждения, которое, как можно было бы ожидать, будет иметь смысл:
Теперь
proc
это указатель на функцию, который ожидает, что адрес5
будет базовым адресом функции, которая принимаетint*
и возвращаетint
.На некоторых микроконтроллерах / микропроцессорах
5
может быть действительный кодовый адрес, и там может быть возможно найти такую функцию.На большинстве компьютеров общего назначения первая страница памяти (адреса
0-1023
для страниц размером 4 КБ) намеренно недействительна (не отображается), чтобы улавливатьnull
обращения к указателям.Таким образом, хотя поведение зависит от платформы, можно разумно ожидать, что произойдет сбой страницы при
*proc
вызове (например,(*proc)(&v)
). До момента*proc
вызова не происходит ничего необычного.Если вы не пишете динамический компоновщик, вам почти наверняка не следует численно вычислять адреса и назначать их переменным, указывающим на функцию.
источник
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/cc1plus.exe -da so.cpp
Эта командная строка генерирует множество промежуточных файлов. Первый из них
so.cpp.170r.expand
, говорит:... int main() () { int D.2229; int _1; ;; basic block 2, loop depth 0 ;; pred: ENTRY _1 = 0; ;; succ: 3 ;; basic block 3, loop depth 0 ;; pred: 2 <L0>: return _1; ;; succ: EXIT } ...
Это все еще не отвечает на вопрос, что именно происходит, но это должен быть шаг в правильном направлении.
источник