2015-12-14 2 views

ответ

5

__LINE__ расширяется до целочисленной константы. Используйте %d печатать:

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

§6.10.8.1 Обязательные макросы (C11 проект)

__LINE__ Предполагаемая номер строки (в пределах текущего источника фи ле) текущей строки источника (AN целочисленная константа).


Если __LINE__ макрос существо перелива int является проблемой, то вы можете привести его к uintmax_t и распечатать его. Это самый безопасный способ, так как uintmax_t - самый большой целочисленный тип.

#include <stdint.h> 

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

Это будет UB, если файл имеет более 32767 строк, а ваша платформа имеет 16 бит 'int'. – Bathsheba

+1

@ Bathsheba В этой логике «долгий срок» тоже не сработает. Как правило, 'int' составляет 32 бита на большинстве платформ, и если ваш исходный файл имеет строки' 4294967296' ('2^32 - 1'), то макрос' __LINE__' является наименьшей из ваших проблем :) –

+0

Хотя это хороший ответ (плюс один), вызывает беспокойство то, что C так пропущен в типе для '__LINE__'. Я до сих пор считаю, что, в балансе, использование '(long) __ LINE__' является самой безопасной задачей. – Bathsheba

0

__LINE__ фактически действует постоянная Integer, и пытается напечатать его в виде строки, то система ищет вещи, не печатать до терминатора, что целая константа не имеет, в результате чего процесс идти в память его не предполагается. В этом случае результатом является segfault.

длинный рассказ короткий, использование %d как спецификатор формата для печати.

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__); 
1

поведения вашей программы неопределенные, так как ваш спецификатор формата является неправильным.

Тем не менее, стандарт С вызывает раздражающее уклонение от типа от __LINE__. Он просто утверждает, что это интегральный тип. Это означает, что это может быть int или, если int не является достаточно большим (int может иметь максимальный размер 32767), то это будет long.

Так, чтобы быть действительно уверены, я бы использовал %ld в качестве спецификатора формата и писать

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

Для действительно большие файлы, я conject это может быть long long типа; то вы бы нужно

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

+0

Где «int» может быть шириной 16 бит? – LPs

+0

Действительно: но вы должны разрешить это для переносимости. – Bathsheba

1

Поскольку __LINE__ целая константа, вы не можете использовать его как строку.Если вам нужна строка, вам нужно сообщить препроцессору, чтобы преобразовать номер в строку:

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

fprintf(stderr, "%s \n", STR(__LINE__)); 
Смежные вопросы