2015-12-24 2 views
14

Я читаю книгу о C, и где-то в коде авторов я нашел определение прототипа функции, затем макрос с тем же именем, и нет определения самой функции ни в любом файле .h10, ни в файле .c ,Зачем определять прототип функции, а затем макрос препроцессора с тем же именем?

Я имею в виду что-то вроде этого:

int print_my_stufff(char *stuff); 
#define print_my_stuff(A) (printf("%s\n", A)) 
/* and print-my-stuff() function never defined anywhere else */ 

код работает, но я просто не понимаю, почему ему нужен прототип функции в первую очередь? Не мог он просто написать макрос? В чем смысл? Должен ли он сказать компилятору, что макрос должен быть оценен для выражения, которое возвращает int или что? Удаление прототипа, похоже, не изменяет поведения. Автор этого не объяснил.

+0

Возможно, это документ макроса. В частности, тип возврата и типы параметров. Автор может делать это только для книги, или автор может даже подумать, что это хорошая практика в целом. – kaylum

+0

Я никогда не видел применения на практике, поэтому я могу только догадываться: возможно, прототип предназначен для документирования типов параметров макроса? –

+1

@kaylum Тогда почему бы просто не написать комментарий? '// этот макрос делает foo' – Arc676

ответ

8

Это устаревшая практика, начиная с inline функций. Если вы вызываете функцию как в print_my_stuff("hello"), тогда препроцессор увидит синтаксис вызова и вставляет содержимое макроса. Если вы используете имя иначе, как в f_ptr = &print_my_stuff, компилятор будет использовать фактическую функцию.

Вызов функции как (print_my_stuff)("hello") также обходит макрос. В некоторых параноидальных руководствах даже требуется заключить в скобки определенные имена функций, потому что Macros Are Evil.

+0

В первом случае, какой адрес он будет использовать? Функция не имеет тела –

+0

@ AndréFratelli В каком случае первый случай? Он никогда не видит никакой функции, если используется макрос. – Potatoswatter

+0

Здесь 'Если вы используете имя иначе, как в f_ptr = & print_my_stuff, компилятор будет использовать фактическую функцию. 'Адрес берется, но какой адрес? –

Смежные вопросы