Adding newline character to printf() changes code behaviour

前端 未结 3 1136
遥遥无期
遥遥无期 2021-01-01 11:48

For some reason, adding \\n to printf() changes the behaviour of below code. The code without \\n prints (null) whereas t

相关标签:
3条回答
  • 2021-01-01 12:11

    Executing with no arguments argv[1] shall be NULL pointer. With argv[1] being NULL

    printf("%s", argv[1]);
    

    will invoke undefined behavior.

    0 讨论(0)
  • 2021-01-01 12:23

    The code has undefined behavior in both cases if the program is not given any command line arguments, so anything can happen.

    Since you are curious (good for you!), here is a potential explanation for what you observe:

    • printf("%s\n", argv[1]); can be optimized by the compiler into puts(argv[1]); whereas printf("%s", argv[1]); still invokes printf().

    • some implementations of printf accept a null pointer as an argument for the %s conversion, hence the output (null).

    • puts() has undefined behavior for a null pointer, in your case a segmentation fault.

    Try compiling both without any optimization (-O0) and see if you get (null) output with and without the \n.

    You can play with godbolt's compiler explorer and see how clang changes behavior with -O0, but not gcc.

    0 讨论(0)
  • 2021-01-01 12:30

    Both are undefined behavior, so an answer could stop right here.

    But there's at least an explanation for the output of (null). This is an extension in glibc (the GNU C library). Passing 0 for %s in printf() is considered undefined in the C standard and therefore could very well result in a crash. The developers of glibc decided to do something meaningful instead.

    The reason the second crashes nevertheless is that with the newline, the compiler decides to optimize: Instead of printf("%s\n", argv[1]), it executes puts(argv[1]), which is semantically equivalent according to the C standard, therefore an allowed optimization. But glibcs "(null)-trick" is only implemented in printf().

    There's another undefined behavior in your program: You potentially access argv out of bounds. There's no guarantee what value you will find at argv[i] when i > argc. There's a slight chance argc could be 0, so you could experience anything else as well.

    0 讨论(0)
提交回复
热议问题