6
int lsdetails(struct stat *astatbuff) {
    printf("%d", astatbuff->st_size);
    printf("%d", astatbuff->st_atime);
    printf("%s\n", getpwuid(astatbuff->st_uid)->pw_name);

    return 0;
    }

warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘__off_t’ [-Wformat]

I received the above error message but I do not understand why. I am under the impression that I am only passing one argument for both st_size and st_atime.

Jens
  • 61,963
  • 14
  • 104
  • 160
user2112062
  • 73
  • 1
  • 5

2 Answers2

8

Unlike C, which starts counting at 0 (array elements :-), gcc starts counting function arguments at 1. So in printf (fmt, value), "argument 1" would refer to fmt, and "argument 2" refers to value. Easy, isn't it?

As for the correct integer type to printf an __off_t, there currently is no 100% guaranteed and portable way. Your best bet is to cast it to the widest unsigned type your implementation supports. Note that an unsigned long may only be 32 bits wide and you'd get problems with files >= 4GB. If you have a C99 implementation, or if it supports unsigned long long, you should be fine with

printf("%llu", (unsigned long long)astatbuff->st_size);

There are discussions in the current POSIX standardization group to provide more printf() format specifiers matching other POSIX types like off_t, pid_t etc. Once that is out the door (don't hold your breath), printing file sizes will be a little more portable and elegant.

Jens
  • 61,963
  • 14
  • 104
  • 160
3

I receive the abover error message but i do not understand why. I am under the impression that i am only passing one argument for both st_size and st_atime.

But you are passing two arguments to printf,

  1. the format string
  2. the struct member

The second argument is of type __off_t, but the format is for int arguments. What the correct format for __off_t is, I don't know, %ld or %zd have a good chance of being correct, but to play it safe, cast to intmax_t and use %jd.

Daniel Fischer
  • 174,737
  • 16
  • 293
  • 422