phoenix
phoenix

Reputation: 559

printf("%%%s","hello")

If I write printf("%%%s","hello"), how is it interpreted as by the compiler? Enlighten me, someone.

Upvotes: 1

Views: 3619

Answers (3)

user142019
user142019

Reputation:

The compiler simply interprets this as calling printf with two strings as arguments (but see Zack's comment).

This happens at compile time (i.e. the compiler does this):

The strings ("%%%s" and "hello") are copied directly into the executable, the compiler leaves them as-is.

This happens at runtime (i.e. the C standard library does this when the app is running):

printf stand for 'print formatted'. When this function is called, it needs at least one argument. The first argument is the format. The next arguments are "arguments" to this format. They are formatted as specified in the first argument.

img


About optimization

I have written an example and ran Clang/LLVM with -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 code

#include <stdio.h>

int main() {
  printf("%%%s", "hello");
  return 0;
}

printftest_unopt.s (not optimized)

; ...
_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 (optimized)

; ...
_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"
; ...

Conclusion

As you can see (in the __TEXT,__cstring,cstring_literals section and the callq to printf), LLVM (a very, very good compiler) does not optimize printf("%%%s", "hello");. :)

Upvotes: 13

Sonny Saluja
Sonny Saluja

Reputation: 7287

%% will print a literal '%' character.

Upvotes: 1

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81724

"%%" means to print an actual "%" character; %s means to print a string from the argument list. So you'll see "%hello".

Upvotes: 7

Related Questions