使用fprintf输出__LINE__时出现分段错误

时间:2015-12-14 10:09:31

标签: c printf

代码如下:

#include <stdio.h>

int main() {

    fprintf(stderr, "%s \n", __LINE__);

    return 0;
}
# gcc b.c
# ./a.out
Segmentation fault (core dumped)

5 个答案:

答案 0 :(得分:5)

__LINE__扩展为整数常量。使用%d进行打印:

fprintf(stderr, "%d \n", __LINE__);

§6.10.8.1强制性宏(C11草案)

  

__ LINE__当前源行的假定行号(在当前源文件中)(整数常量)。

如果__LINE__宏溢出int是一个问题,那么您可以将其转换为uintmax_t并打印它。这是最安全的方式,因为uintmax_t是最大的整数类型。

#include <stdint.h>

fprintf(stderr, "%ju \n", (uintmax_t)__LINE__);

答案 1 :(得分:1)

由于格式说明符不正确,程序的行为是 undefined

然而,C标准在__LINE__类型上令人恼火地失效。它只是说它是一个整体类型。这意味着它可能是int,或者,如果int不够大(int的最大大小可能为32767),那么它将是long

所以要确定,我会使用%ld作为格式说明符并编写

fprintf(stderr, "%ld \n", (long)__LINE__);

对于真正的大文件,我推测它可能是long long类型;那你呢 需要

fprintf(stderr, "%lld \n", (long long)__LINE__);

答案 2 :(得分:1)

由于__LINE__是一个整数常量,因此不能将其用作字符串。如果需要字符串,则必须告诉预处理器将数字转换为字符串:

#define STRINGIFY(x) #x
#define STR(x) STRINGIFY(x)

fprintf(stderr, "%s \n", STR(__LINE__));

答案 3 :(得分:0)

__LINE__实际上实际上是一个整数常量,并且通过尝试将其作为字符串打印,系统会搜索要打印的内容,直到终结符(整数常量不具有),导致进程继续进入记忆不应该。在这种情况下,结果是一个段落错误。

长话短说,使用%d作为格式说明符来打印它。

答案 4 :(得分:0)

__LINE__至少需要%d格式,因为它是一个整数常量。

一个好的提示:始终使用-Wall选项进行编译。在你的情况下,你会看到:

b.c: In function ‘main’:
b.c:5:5: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
     fprintf(stderr, "%s \n", __LINE__);