Это полностью зависит от вашей реальной ситуации.Если возможно, я бы предпочел метод A, потому что он проще читать и создавать более чистый код, в частности, если ваша функция имеет возвращаемое значение:
ret = callbacks[UPDATE_EVENT](sender);
// is nicer then
if (callbacks[UPDATE_EVENT])
ret = callbacks[UPDATE_EVENT](sender);
else
ret = 0;
Конечно, метод A становится tedouis, когда вы не толькоподпись одной функции, но скажем, 100 разных подписей.И для каждого вы должны написать нулевую функцию.
Для оценки производительности зависит, является ли nullcallback () редким случаем или нет.Если это редко, метод А, очевидно, быстрее.Если нет, метод B мог бы быть немного быстрее, но это зависит от многих факторов: какую платформу вы используете, сколько аргументов имеют ваши функции и т. Д. Но в любом случае, если ваши обратные вызовы выполняют «реальную работу», т.е.не только некоторые простые вычисления, это не должно иметь никакого значения.
Когда ваш метод B действительно может быть быстрее, это когда вы не только вызываете обратный вызов для одного отправителя, но и для очень многих:
extern void *senders[SENDERS_COUNT]; // SENDERS_COUNT is a large number
if (callbacks[UPDATE_EVENT])
{
for (int i = 0; i < SENDERS_COUNT; i++)
callbacks[UPDATE_EVENT](senders[i]);
}
Здесь весь цикл пропускается, когда нет действительного обратного вызова.Эту настройку также можно выполнить с помощью метода A, если известен адрес nullcallback (), т.е.не определено только в каком-либо модуле.