char *test = NULL; printf("%s\n", test);
위 코드의 결과는
segmantation Fault
char *test = NULL; printf("%s", test);
(null)
설명좀 해주실분 계신가용?
[bushi@rose net]$ echo "int main(){printf(\"%s\\n\", (void*)0);}" > x.c [bushi@rose net]$ echo "int main(){printf(\"%s\", (void*)0);}" > y.c [bushi@rose net]$ gcc -o x.s -S x.c x.c: In function ‘main’: x.c:1: warning: incompatible implicit declaration of built-in function ‘printf’ [bushi@rose net]$ gcc -o y.s -S y.c y.c: In function ‘main’: y.c:1: warning: incompatible implicit declaration of built-in function ‘printf’ [bushi@rose net]$ [bushi@rose net]$ diff -u x.s y.s --- x.s 2012-09-27 19:14:04.528890547 +0900 +++ y.s 2012-09-27 19:14:10.503890580 +0900 @@ -1,4 +1,7 @@ - .file "x.c" + .file "y.c" + .section .rodata +.LC0: + .string "%s" .text .globl main .type main, @function @@ -7,8 +10,9 @@ movl %esp, %ebp andl $-16, %esp subl $16, %esp - movl $0, (%esp) - call puts + movl $0, 4(%esp) + movl $.LC0, (%esp) + call printf leave ret .size main, .-main [bushi@rose net]$
흥미롭군요. \n으로 끝나는 문자열은 printf 대신 puts로 치환되는 건가요?
이런 최적화는 preprocessor 수준에서 일어나는건지 컴파일러 수준에서 일어나는건지 궁금하네요.
glibc-2.15-r2 Gentoo on x86_64
위 환경에서는
printf( "%s", NULL ); printf( "%s ", NULL ); printf( "%s\n", NULL );
모두 printf를 호출합니다.
아마 glibc버젼에 따라 다른 동작을 하지 않을까 싶습니다.
\n으로 끝나는 문자열은 printf 대신 puts로 치환되는 건가요?
제 추측으로는, \n뿐만이 아니라, format string이 오직 하나의 %s혹은 %c argument를 가지고 있고, 그 format string은 argument를 제외한, 어떠한 다른 character도 포함하지않으며 해당 argument의 내용과 길이가 컴파일 타임에 알려져있는가를 판단할것같습니다.
즉, 한번의 puts()/putc()로 치환할수 있으면 치환할것이고 그렇지 않으면, 그냥 printf()에 넘기지 않을까 생각이 드네요.
gcc 는 몇몇 함수들에 대해서는 builtin 함수를 호출하는 경우가 있습니다. -fno-builtin 관련 옵션을 보면 될 것 같네요.
http://www.acsu.buffalo.edu/~charngda/gcc_printf.htmlhttp://nion.modprobe.de/blog/archives/680-gcc-and-printfputs-optimizations.html
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
텍스트 포맷에 대한 자세한 정보
<code>
<blockcode>
<apache>
<applescript>
<autoconf>
<awk>
<bash>
<c>
<cpp>
<css>
<diff>
<drupal5>
<drupal6>
<gdb>
<html>
<html5>
<java>
<javascript>
<ldif>
<lua>
<make>
<mysql>
<perl>
<perl6>
<php>
<pgsql>
<proftpd>
<python>
<reg>
<spec>
<ruby>
<foo>
[foo]
[bushi@rose net]$ echo "int
흥미롭군요. \n으로 끝나는 문자열은 printf
흥미롭군요. \n으로 끝나는 문자열은 printf 대신 puts로 치환되는 건가요?
이런 최적화는 preprocessor 수준에서 일어나는건지 컴파일러 수준에서 일어나는건지 궁금하네요.
glibc-2.15-r2 Gentoo on
glibc-2.15-r2
Gentoo on x86_64
위 환경에서는
printf( "%s", NULL );
printf( "%s ", NULL );
printf( "%s\n", NULL );
모두 printf를 호출합니다.
아마 glibc버젼에 따라 다른 동작을 하지 않을까 싶습니다.
\n으로 끝나는 문자열은 printf 대신 puts로 치환되는 건가요?
제 추측으로는, \n뿐만이 아니라, format string이
오직 하나의 %s혹은 %c argument를 가지고 있고,
그 format string은 argument를 제외한, 어떠한 다른 character도 포함하지않으며
해당 argument의 내용과 길이가 컴파일 타임에 알려져있는가를 판단할것같습니다.
즉, 한번의 puts()/putc()로 치환할수 있으면 치환할것이고
그렇지 않으면, 그냥 printf()에 넘기지 않을까 생각이 드네요.
음 ..
gcc 는 몇몇 함수들에 대해서는 builtin 함수를 호출하는 경우가 있습니다.
-fno-builtin 관련 옵션을 보면 될 것 같네요.
http://www.acsu.buffalo.edu/~charngda/gcc_printf.html
http://nion.modprobe.de/blog/archives/680-gcc-and-printfputs-optimizations.html
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
댓글 달기