2012-05-05 2 views
0

Я получаю ошибку «int format, different type arg (arg 4)» на последней строке. Должен ли я просто использовать int или есть лучший способ справиться с этим?Cast off_t to int

struct stat info; 
if (stat(file_path, &info) == -1 || errno == ENOENT) 
    return -1; 

if (stat(file_path, &info) != -1) 
{ 
    char buf[LINELEN]; 
    snprintf(buf,LINELEN,"File Size: %d",info.st_size); 
+3

Плохая вещь о 'printf' (и это делает меня действительно грустным) именно эта проблема с строкой формата. Представьте свой код, который typedefs типа либо 'uint32_t', либо' uint64_t' в зависимости от некоторой конфигурации. Вы никогда не можете просто распечатать эти переменные. Однако решение, которое наиболее определенно всегда работает без проблем, состоит в том, чтобы отнести аргументы к максимальному размеру, который они могут принять. Например, в вашем случае: 'printf ("% lu ", (unsigned int) info.st_size);' который печатает правильно независимо от размера. Проблема только в том, что аргумент больше, чем ваш бросок. Вы потеряете данные, но все равно избегаете UB. – Shahbaz

ответ

0

Попробуйте вместо этого формат% ld. Это зависит от вашей платформы, но обычно off_t определяется как долго. Также может быть неподписанным, в этом случае используйте% lu.

0

Для off_t типа, вы должны напечатать это следующим образом:

snprintf(buf,LINELEN,"File Size: %jd",info.st_size); 

Обратите внимание на j в форматере.

+0

Формат «j» предназначен для '{u} intmax_t'. Таким образом, вы должны были бы бросить этот тип, чтобы быть уверенным. –

0

st_size имеет тип off_t, что действительно является long.

Так правильный вызов должен быть:

snprintf(buf,LINELEN,"File Size: %ld",info.st_size); 
+0

"действительно длинный"? Это может быть любой целочисленный тип со знаком. –

+0

Итак, вы думаете, что модификатор «j» будет присутствовать во всех реализациях? предполагая, что это долгое время безопаснее. Вы можете сделать st_size длинным без предупреждения компилятора: 'snprintf (buf, LINELEN,« Размер файла:% ld », (long) info.st_size);' –

+0

модификатор «j» является частью стандарта C. AFAIR это так, начиная с C99. –

3

К сожалению, не существует формат, определенный для off_t, который может быть любой целочисленный тип, в зависимости от платформы, а также на некоторых макросов (которые регулируют, если вы можете получить доступ к файлы размером более 4 ГБ, например). Вы не можете полагаться на что-либо из этого. Лучше всего использовать «j» в качестве модификатора длины в вашем формате printf и указать значение intmax_t.

0

Для обеспечения безопасности, правильности и переносимости: всегда указывайте явное приведение при передаче varargs, например, printf, если предмет, который вы передаете, может не иметь того же типа, где бы вы ни компилировались. Например, выясните, насколько велики вы думаете, что off_t может получить (длинный должен быть по крайней мере столь же большим, как off_t всюду), придать этому и убедиться, что ваш формат printf принимает долгое, что вы теперь благополучно знаете, что будете проходить Printf без броска для типов, которые могут меняться, задает проблемы.