Указатели функции в C - “ненужная” операция взятия адреса

Используйте это:

border-radius: 4px;
box-shadow: 0 1px 6px 0 rgba(32,33,36,0.28);
border-color: rgba(223,225,229,0);
7
задан Nicol Bolas 31 March 2012 в 17:26
поделиться

6 ответов

Чувствуете ли Вы себя неловко, или не не изменяет то, что C не считают безопасным с точки зрения типов языком. Рассматриваемый вопрос:

int main()
{
   int integer = 0xFFFFFF; 
   void (*functionPointer)() = (void(*)())integer; 

   functionPointer(); 

   return 0; 
}

Это абсолютно допустимо во время компиляции, но это, очевидно, не безопасно.

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

Ну, ответ - то, что передача функции значением приводит к указателю функции, тот же путь, как передача массива значением приводит к указателю на свой первый элемент. каждый говорит что массив и функциональное "затухание". существует только несколько случаев, где того затухания не происходит. например, sizeof (массив) приводит к sizeof массив, не тот его первого указателя элемента. sizeof (функция) недопустим (функции не являются никакими объектами), необходимо сделать sizeof (&function). Другие случаи связывают со ссылками:

void baz();

void foo(void (&bar)()) {
    bar();
}

// doesnt work, since a reference to a function is requested. 
// you have to pass 'bar' itself, without taking its address 
// explicitely.
foo(&baz);  

Это, btw все является причиной, которую можно сделать

template<typename T, int N>
void ByRef(T (&foo)[N]) { 
    ...
}

так как массив еще не затухает при рассмотрении параметров ссылки.

5
ответ дан 6 December 2019 в 08:17
поделиться

Я подозреваю, что Вы только чувствуете себя неловко, потому что Вы не привыкли к кодированию как 'близко к металлу', поскольку C позволяет. Причина, почему C не требует операции вычисления адреса на функциях, состоит в том, что нет ничего, кроме чего можно действительно сделать с функциями, называют их или передают их.

Другими словами, нет никакого разумного определения для управления 'значением' функции.

Принимая во внимание, что с ints, можно добавить к или вычесть из значения, это не имеет никакого смысла для функций.

В любом случае C предшествует и C++ и его собственной стандартизации - исходному K&R C даже не прототипы и ANSI, чтобы удостовериться, что их стандартизация не взломала существующий код как можно больше.

4
ответ дан 6 December 2019 в 08:17
поделиться

Это - деталь синтаксиса. Если Вам не нравится не использовать и указывать, что указатель функции затем всегда использует его. Если Вам нравится сохранять дополнительные нажатия клавиш, и не быть столь же явным в Вашем кодировании затем используют в своих интересах его.

Что касается безопасности типов я не вижу, как это имеет любое значение. Компилятору дают функцию как аргумент, и он может разработать то, что функциональная подпись полностью с имени. То, что Вы не называете его (с () синтаксис) дает всему признаку потребности компилятора, что Вы хотите указатель функции в этом месте. И просто синтаксическая точность, чтобы указать людям, что они смотрят на указатель некоторого описания.

Если бы Вы используете C++, то я предложил бы смотреть на функторы повышения как на более хороший метод раздавания функций так или иначе. Эти прекрасные объекты позволяют объединенный и довольно ясный синтаксис для всех функций в C++ :)

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

Это не так ощущение дискомфорта как отвращение к valid-yet-conflicting опциям синтаксиса. Также cmp указатель и должен последовательно рассматриваться как таковой, или именно некоторый другой тип - по моему скромному мнению, синтаксически вводит в заблуждение.

Идя немного далее, я также потребовал бы, чтобы вызов любой разыменовал указатель (для выделения того, что это - указатель), или не (потому что имя функции является указателем)..., но не позволяют обоим.

Указатели функции могут быть чрезвычайно мощными, все же они, кажется, источник беспорядка и новым и опытным программистам одинаково. Часть трудности могла быть облегчена путем требования единственного, значимого синтаксиса, который разъясняет их использование, вместо того, чтобы затенить ее.

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

Обратите внимание, что то же идет для 'разыменования' (т.е. вызов) указатели функции; Вы не имеете к

(*funcptr)(arg1, arg2);

как

funcptr(arg1, arg2);

будет достаточен.

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