0
votes

Do we use lu and unsigned long cast like in:

printf("%lu\n", (unsigned long)BUFSIZ); /* 512 */

and hope for the best? or there is another way?

And this is not a duplicate of: How can one print a size_t variable portably using the printf family? simply because I don't know what BUFSIZ type is.

3
you can cast it, then use the size_t advice from the duplicate :/Antti Haapala
@AnttiHaapala seriously? how can I know that BUFSIZ is of type size_t if @Felix Palmen didn't give me the answer? My question is not about how to print size_t, its about BUFSIZ which I don't know even what type it is.Bite Bytes
it is a size, which you can assume you can cast as size_t without loss of information.Antti Haapala
You have not even shown BUFSIZ. If it is a macro with an unqualified integer value, then it is of type int.Weather Vane

3 Answers

4
votes

I assume BUFSIZ is always a value fitting into size_t and there are no other guarantees.

In that case: Yes, this is the most correct way to do it if you're limited to . The lack of a format length modifier suitable for size_t is one of the many shortcomings in this very old standard. In practice, if you're on a 64bit system with LLP64 data model (this is, Win64), size_t is indeed larger than long and this code can break for large sizes. Thanks EOF for the hint. Still in practice: It probably should be defined reasonably and an I/O-Buffer sized 4G or larger doesn't sound reasonable, so it really is unlikely to run into problems with the "casting to unsigned long" approach.

Additional note: There might be a valid reason to use this construct even with a compiler in or mode, and that is portability to the windows platform. Microsoft's msvcrt (the C runtime and standard library) doesn't support the z length modifier.

1
votes

According to the C Standard (7.21 Input/output )

SETBUF

which expands to an integer constant expression that is the size of the buffer used by the setbuf function;

It is unspecified what is the type of the constant.

On the other hand the standard function setvbuf can be used to specify a user-supplied buffer or the buffer allocated by the function. It has the following declaration

int setvbuf(FILE * restrict stream,
char * restrict buf,
int mode, size_t size);

where the parameter size of the type size_t specifies the size of the buffer.

As the size can not be a negative number then you may output its value as having the type size_t.

1
votes

Well, it is easy to find proof that BUFSIZ is certainly not always of type size_t. Consider the following fragment test.c:

#include <stdio.h>
BUFSIZ

Compile it on Linux and:

% gcc -E test.c|tail -n 2
# 2 "test.c" 2
8192

Thus, it certainly isn't of type size_t always. The constant migth be of type int but it might also not be an int, so the safest should be to assume that it can be cast as size_t since the argument to setvbuf is also of type size_t.

Then, use the advice from How can one print a size_t variable portably using the printf family?