0

For a school project, I'm trying to re-create the printf function of the stdio.h library in C.

I'm currently working on getting the unsigned int printing part working, but for some reason, why I try the real printf to print an unsigned int, it gives me a warning (which is considered as an error in my school). Could you someone explain me why?

Here is the code line I have used: printf("%u\n", 4294967295);. And here is the error I'm gettting:

main.c:18:17: warning: format specifies type 'unsigned int' but the argument has type 'long' [-Wformat]
        printf("%u\n", 4294967295);
                ~~     ^~~~~~~~~~
                %ld
1 warning generated.
Max
  • 7
  • 3

3 Answers3

0

The type of an integer literal is taken as the first type in the list in the standard that fits. The list for literals without the any suffix is int, long int, long long int/unsigned long int. As 4294967295 doesn't fit in int, it'll be long if long is a type wider than 32-bit (which is the case on your platform). To get an unsigned int literal you need to use the U suffix

The type of integer constant

The type of the integer literal is the first type in which the value can fit, from the list of types which depends on which numeric base and which integer-suffix was used.

Types allowed for integer constants:

  • no suffix
    • decimal bases:
      • int
      • long int
      • unsigned long int (until C99)
      • long long int (since C99)
    • other bases:
      • int
      • unsigned int
      • long int
      • unsigned long int
      • long long int (since C99)
      • unsigned long long int (since C99)
  • ...

If the value of the integer constant is too big to fit in any of the types allowed by suffix/base combination and the compiler supports extended integer types (such as __int128), the constant may be given the extended integer type; otherwise, the program is ill-formed.

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • This is kind of a C++ answer. C does not have binary base and in case a number does not fit in an extended integer type, it has no type - it is not "ill-formed", there's nothing called ill-formed in C. – Lundin Dec 17 '20 at 10:46
  • @Lundin C23 has binary integer literal https://en.cppreference.com/w/c/language/integer_constant – phuclv Dec 17 '20 at 14:37
  • That remains to be seen, that standard is still in development. – Lundin Dec 17 '20 at 14:40
0

All integer constants such as 4294967295 have a type, just like declared variables. The C compiler assigns a type to such a constant based on various intricate rules. A simplified explanation is that these rules basically boil down to:

  • "Does it fit in an int? If so, make it int."
  • "Otherwise does it fit in a long?" ... and so on.

Note that these default types are signed types.

On a 32 bit computer with 32 bit int, the largest number you can store in an int is 2^31 - 1 = 2147483647. 4294967295 is larger than that, so the compiler has to store it in a long. Hence the warning.

Since 4294967295 would have fit in an unsigned int, so you could fix the code by simply forcing the compiler to treat the integer constant as unsigned: 4294967295u.

Lundin
  • 195,001
  • 40
  • 254
  • 396
-1

It seems you are trying to print an unsigned int, but the value you passed in the printf("%u\n", 4294967295) is of type long. So you can try changing the datatype to unsigned long int

Zach_Mose
  • 357
  • 3
  • 7