Re Legacy code : format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat] Re Legacy code : format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat] unix unix

Re Legacy code : format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat]


Use format specifier %lu instead of %d and your compiler should stop complaining.

printf("Approximately %lu.%lu' of tape used\n", count/bpi/12, (count*10/bpi/12)%10);


This is undefined behavior, which means anything can happen including appearing to work correctly and then break later on down the road.

Looking at the source we can see both count and bpi are unsigned long:

extern unsigned long bpi; /* tape density in bits per inch */extern unsigned long count; /* count of tape frames written */ 

the correct format specifier for these would be %lu.

The first argument to printf specifies a string to print out which can contain conversion specifiers beginning with % that usually specifies the types of the subsequent arguments, so in your example:

"Approximately %d.%d' of tape used\n"               ^^ ^^               1  2

both conversion specifiers 1 and 2 are %d which means that printf will expect the next two arguments to be of type int but they are really of type unsigned long.

If we look at the draft C99 standard section 7.19.6.1 The fprintf function which also covers printf for format specifiers, says:

If a conversion specification is invalid, the behavior is undefined.248) If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

so you need to fix the format specifier which is incorrect and your warning will go away and you will be back in well defined behavior land.


Use %lu instead of %d. %d is used for type int, %lu for unsigned long.