Компилятор просто интерпретирует это как вызов printf
с двумя строками в качестве аргументов (но см. Комментарий Зака).
Это происходит во время компиляции (т.е. это делает компилятор):
Строки ("%%%s"
и "hello"
) копируются непосредственно в исполняемый файл, компилятор оставляет их как есть.
Это происходит во время выполнения (т. Е. Стандартная библиотека C делает это при запуске приложения):
printf
означает «отформатированный».Когда эта функция вызывается, ей нужен хотя бы один аргумент.Первый аргумент - это формат.Следующие аргументы являются «аргументами» в этом формате.Они отформатированы так, как указано в первом аргументе.
Об оптимизации
Я написал пример и запустил Clang / LLVM с -S
:
$ emacs printftest.c
$ clang printftest.c -S -o printftest_unopt.s # not optimized
$ clang printftest.c -S -O -o printftest_opt.s # optimized: -O flag
код C
#include <stdio.h>
int main() {
printf("%%%s", "hello");
return 0;
}
printftest_unopt.s (не оптимизировано)
; ...
_main:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl $0, %eax
movl $0, -4(%rbp)
movl %eax, -8(%rbp)
xorb %al, %al
leaq L_.str(%rip), %rdi
leaq L_.str1(%rip), %rsi
callq _printf ; printf called here <----------------
movl %eax, -12(%rbp)
movl -8(%rbp), %eax
addq $16, %rsp
popq %rbp
ret
.section __TEXT,__cstring,cstring_literals
L_.str:
.asciz "%%%s"
L_.str1:
.asciz "hello"
; ...
printftest_opt.s (оптимизировано)
; ...
_main:
pushq %rbp
movq %rsp, %rbp
leaq L_.str(%rip), %rdi
leaq L_.str1(%rip), %rsi
xorb %al, %al
callq _printf ; printf called here <----------------
xorl %eax, %eax
popq %rbp
ret
.section __TEXT,__cstring,cstring_literals
L_.str:
.asciz "%%%s"
L_.str1:
.asciz "hello"
; ...
Заключение
Как вы можете видеть (в __TEXT,__cstring,cstring_literals
разделе и от callq
до printf
), LLVM (очень, очень хороший компилятор) делает не оптимизировать printf("%%%s", "hello");
.:)