向printf()添加换行符会更改代码行为 [英] Adding newline character to printf() changes code behaviour
问题描述
由于某些原因,将\n
添加到printf()
会更改以下代码的行为.没有\n
的代码将显示(null)
,而具有\n
的代码将导致Segmentation fault
.
For some reason, adding \n
to printf()
changes the behaviour of below code. The code without \n
prints (null)
whereas the code with \n
leads to Segmentation fault
.
Printf.c
#include <stdio.h>
int main(int argc, char* argv[]){
printf("%s", argv[1]);
}
Printf.c-输出
$ gcc -o Printf Printf.c
$ ./Printf
(null)
Printf_Newline.c
#include <stdio.h>
int main(int argc, char* argv[]){
printf("%s\n", argv[1]);
}
Printf_Newline.c-输出
$ gcc -o Printf_Newline Printf_Newline.c
$ ./Printf_Newline
Segmentation fault (core dumped)
我很好奇这背后的原因.
I am curious to understand the reason behind this.
推荐答案
两者都是未定义的行为,因此答案可以就此结束.
Both are undefined behavior, so an answer could stop right here.
但是至少对(null)
的输出有一个解释.这是glibc
(GNU C库)中的扩展.在C标准中,将printf()
中的%s
传递给0
被视为未定义,因此很可能导致崩溃. glibc
的开发人员决定做一些有意义的事情.
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.
尽管如此,第二次崩溃的原因是,对于换行符,编译器决定进行 optimize :它代替printf("%s\n", argv[1])
而是执行puts(argv[1])
,根据C标准,它在语义上是等效的,因此是允许的优化.但是glibc
的(空)技巧"仅在printf()
中实现.
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 glibc
s "(null)-trick" is only implemented in printf()
.
程序中还有一个未定义的行为:您可能会访问argv
越界.不能保证在i > argc
时在argv[i]
处会找到什么值. argc
可能为0,所以您可能还会遇到其他任何情况.
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.
这篇关于向printf()添加换行符会更改代码行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!