向printf()添加换行符会更改代码行为 [英] Adding newline character to printf() changes code behaviour

查看:98
本文介绍了向printf()添加换行符会更改代码行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于某些原因,将\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 glibcs "(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆