相关疑难解决方法(0)

使用printf的%s说明符打印NULL的行为是什么?

遇到一个有趣的采访问题:

test 1:
printf("test %s\n", NULL);
printf("test %s\n", NULL);

prints:
test (null)
test (null)

test 2:
printf("%s\n", NULL);
printf("%s\n", NULL);
prints
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

虽然这可能在某些系统上运行良好,但至少我的方法正在抛出一个分段错误.这种行为最好的解释是什么?以上代码在C中.

以下是我的gcc信息:

deep@deep:~$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Run Code Online (Sandbox Code Playgroud)

c linux language-lawyer compiler-bug

48
推荐指数
4
解决办法
4万
查看次数

printf("%x",1)是否会调用未定义的行为?

根据C标准(6.5.2.2第6段)

如果表示被调用函数的表达式具有不包含原型的类型,则对每个参数执行整数提升,并将具有float类型的参数提升为double.这些被称为默认参数促销.如果参数的数量不等于参数的数量,则行为未定义.如果函数是使用包含原型的类型定义的,并且原型以省略号(,...)结尾,或者促销后的参数类型与参数类型不兼容,则行为未定义.如果函数是使用不包含原型的类型定义的,并且促销后的参数类型与促销后的参数类型不兼容,则行为未定义,但以下情况除外:

  • 一个提升类型是有符号整数类型,另一个提升类型是相应的无符号整数类型,并且该值可在两种类型中表示;
  • 这两种类型都是指向字符类型或空格的限定或不合格版本的指针.

因此,一般来说,只要传递的值适合两种类型,传递int到需要unsigned int(或反之亦然)的可变函数是没有错的.但是,printf读取规范(7.19.6.1第9段):

如果转换规范无效,则行为未定义.如果任何参数不是相应转换规范的正确类型,则行为未定义.

签名/未签名不匹配也不例外.

这是否意味着printf("%x", 1)调用未定义的行为?

c standards printf variadic-functions language-lawyer

31
推荐指数
3
解决办法
1730
查看次数

将NULL传递给printf%s

#include<stdio.h>
#include<string.h>

int main() {
    char *ptr = NULL;

    printf("%s", ptr);//The output is null
    //  printf("%s\n", ptr); //addition of **\n** give segmentation fault 

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

第一个printf输出:(null).但为什么第二个printf产出是: Segmentation fault (core dumped)只是添加:\n

c

1
推荐指数
1
解决办法
1344
查看次数