Вы всегда можете избежать расширения функциональных подобных макросов с помощью скобки имя:
(putc)('c', outfile);
Это специально разрешается стандартом C, в § 7.1.4 («Использование библиотечных функций») (акцент добавлено):
Любая функция, объявленная в заголовке, может быть дополнительно реализована как функционально подобный макрос, определенный в заголовке, поэтому, если функция библиотеки объявлена явно, когда заголовок включен, один из методов, показанных ниже могут быть использованы для обеспечения декларации на такой макрос не влияет. Любое макроопределение функции может быть подавлено локально, включив имя функции в круглых скобках, так как вместо этого имя не следует левой скобкой, которая указывает на расширение имени функции макрофункции.
В частном случае стандартной реализации библиотеки в комплекте с НКОЙ, вы, вероятно, обнаружите, что использование fputc
вместо putc
результатов фактического вызова fputc
. (Стандарт требует базовой функциональности fputc
, чтобы быть идентичной putc
, это позволяет макро реализации putc
- если есть один - оценить второй аргумент более чем один раз.)
Для чего это стоит, я проверил использование gcc 5.2.0 и оказалось, что fprintf
переведен на звонок fputc
, а не putc
. Явное обращение putc
действительно расширило макрос до вызова __IO_putc
, но этого можно избежать, как указано выше.
Пример программы:
#include <stdio.h>
int main() {
FILE* outfile = stdout;
fprintf(outfile, "c");
putc('c', outfile);
(putc)('c', outfile);
return 0;
}
Сгенерированный код (добавлены комментарии):
main:
pushq %rbx
movq stdout(%rip), %rbx
movl $99, %edi
movq %rbx, %rsi
call fputc # fprintf(outfile, "c")
movq %rbx, %rsi
movl $99, %edi
call _IO_putc # putc('c', outfile)
movq %rbx, %rsi
movl $99, %edi
call putc # (putc)('c', outfile);
xorl %eax, %eax
popq %rbx
ret
Любая причина, по которой вы не хотите, чтобы эти символы были в двоичном формате? – Macmade
__IO_putc - внутренняя функция glibc, но эта функция создает проблемы, когда я хочу сделать что-то вроде кросс-компиляции или двоичного перевода. – hwliu
Вы спрашиваете, как предотвратить замену 'printf' на' putc'? –