Search code examples
linuxgccprintfnewlinecarriage-return

How do I stop GCC stripping trailing newline from string literal in obj file?


Working under Linux, i just met the following issue. (For sure, someone will give me the answer, but up to now,i didn't find any simple and clear answer :)

/*compile with gcc -o out.x hello.c*/

#include<stdio.h>

int main()
{
    printf("Hello World2\r\n");
    printf("Hello World3\r\n ");

 return 0;
}

Running the following code under Linux give two strings BUT the ending char are differents: the first output ends with 0x0d while the 2nd ends with 0x0d,0x0a.

This is something done by the compiler (GCC) as you can see in the obj file:

Contents of section .rodata:
 400610 01000200 48656c6c 6f20576f 726c6432  ....Hello World2
 400620 0d004865 6c6c6f20 576f726c 64330d0a  ..Hello World3..
 400630 2000                                  .              

So, questions are:

  • Why ?
  • How can i avoid this kind of "optimization"(!?)

Thanks


Solution

  • Creating formatted output at runtime takes time; the printf call is slow. GCC knows this, so replaces the first function with a call to puts. Since puts automatically adds a \n, GCC needs to remove the \n from the string to compensate.

    GCC does this because it considers printf a built-in. Because this has no effect on the bytes output or even on the number of calls to write; I strongly recommend leaving it as-is. If you do want to disable it, you can pass -fno-builtin-printf, but the only effect will be to slow down your code as it tries to format the string unnecessarily.