0

If i cast a variable type called "a" to another variable type called "b", "b" now is "a" interpreted as the new variable type. And if I have one variable type called "a" and I printf it with another variable type, the output will be "a" interpreted as the new variable type. So is printf making a hidden casting process to do that?

rayo7
  • 13
  • 4
  • 2
    Code example would help understand your question better, but if you mean like `printf("%d\n", pointer)`, then, yes, `printf` is casting the `pointer` argument to an `int` internally. (However, that is a "reinterpret" cast, not "convert" cast, since the original type is not known to `printf`.) – Arkku Nov 29 '21 at 16:23
  • So why if float a=12.56 and I printf("%d", a) it shows an undefined value if it should be casting a to int and this should be 12. This is not the same as float a =12.56 int b = (int) a printf("%d", b). It should be the same as supposedly printf does an internal casting as in the second example of declaren b as an int cast of a... – rayo7 Nov 29 '21 at 16:27
  • That's what I mean by reinterpreting cast rather than conversion; `printf` does not know that it is a `float`; it is just passed some argument and it assumes that you passed the correct type of argument for the format specifier, as per contract of `printf`. (i.e., your assertion that "this should be 12" is incorrect) – Arkku Nov 29 '21 at 16:29
  • Anyway, I suggest posting a complete code example in the question, then you can explain what you expect to happen and what happens instead. – Arkku Nov 29 '21 at 16:33
  • Also a good point in [this answer](https://stackoverflow.com/a/70158054/204883) about different types of arguments being potentially passed differently, so indeed you might not even get the reinterpret cast if that happens. In any case this is undefined behaviour, and a programming error since you are violating the contract of `printf`. – Arkku Nov 29 '21 at 16:36
  • (Note that you can easily cast the argument when you call it, i.e., `printf("%d", (int) my_float)` is entirely valid and works as you expect.) – Arkku Nov 29 '21 at 16:37
  • So why if i have short a=-1 and I printf ("%hu", a) it shows me the same value asi if I use unsigned short b = (unsigned short)a and I printf("%hu", b) Now it shows the same value in both examples and in the comment before it was the same but instead of short it was Int. Why here is the same? – rayo7 Nov 29 '21 at 16:38
  • Because *signed* and *unsigned* short will be represented by the same bits in memory UNLESS the signed value is NEGATIVE - then it will be represented as TWOS COMPLIMENT (on most implementations) and the values produced by `printf()` will be wildly different. (one negative signed output with `%hd` and the unsigned representation of twos compliment of that number with `%hu`) – David C. Rankin Nov 29 '21 at 16:41
  • Signed and unsigned versions of the same type are often interchangeable in machine code, and indeed the bit pattern of `-1` and `(unsigned) -1` is the same (for the common two's complement representation). – Arkku Nov 29 '21 at 16:41
  • Fun exercise: try doing some addition of binary numbers by hand, e.g., pretend you have 4-bit signed and unsigned types in two's complement and list all bit patterns and their values i signed/unsigned (there's only 16 patterns, so 32 combined values). – Arkku Nov 29 '21 at 16:46
  • FWIW, this question is in part a continuation of a long comment chain at https://stackoverflow.com/questions/70155700/why-if-a-read-a-float-and-i-printf-it-as-an-int-it-shows-a-random-value-c – Steve Summit Nov 29 '21 at 17:22
  • Be careful with your definitions: a *cast* is a piece of syntax (an operator) which requests a *conversion*. And, whether or not you use an explicit cast, an *assignment* always implies a conversion, if necessary. In fact, one definition of the cast operator is that it gives you whatever you would have gotten if you had assigned the casted value to a variable of that type. – Steve Summit Nov 29 '21 at 17:29
  • The thing you have to understand about `printf` is that it is *different*. For virtually every other function, the function prototype tells the compiler both what the return value is, and what arguments are expected. So if you call `sqrt(144)`, that `int` value `144` is automatically converted to type `double`, because the prototype says so. But for `printf`, this type of automatic conversion to the expected type is *not performed*. If you say `(printf("%f\n", 144)`, what you have is *undefined behavior*, and it doesn't work. – Steve Summit Nov 29 '21 at 17:32
  • There are some automatic conversions performed when you call `printf`, but they're completely different. They're called the [default argument promotions](https://stackoverflow.com/questions/1255775/default-argument-promotions-in-c-function-calls). They're the ones I was alluding to in [this comment](https://stackoverflow.com/questions/70155700/why-if-a-read-a-float-and-i-printf-it-as-an-int-it-shows-a-random-value-c#comment124016182_70155700). – Steve Summit Nov 29 '21 at 17:32

1 Answers1

2

If i cast a variable type called "a" to another variable type called "b", "b" now is "a" interpreted as the new variable type.

No, a cast converts a value to another type; it does not reinterpret a variable. If a is an int with value 3, then (float) a is a float with the same value, 3.

And if I have one variable type called "a" and I printf it with another variable type, the output will be "a" interpreted as the new variable type. So is printf making a hidden casting process to do that?

Answering the second question first, no, printf is not doing any casting in this case. Regarding the first question, that is the output that may appear in some cases. But the behavior is not defined by the C standard. Some of the things that may happen include:

  • You pass a variable a of one type but tell printf to expect another type. printf fetches the bytes of the argument from where you put the bytes of a, but, because it expects a different type, it interprets the bytes as if they were encoded using the rules for the other type, so it reinterprets the bytes of a as the new type.
  • You pass a variable a of one type but tell printf to expect another type. However, the rules for passing these types say to pass them in different places. a might be passed in a general processing register, but the other type might be passed in a floating-point register. So printf fetches the bytes from where it expects them to be, but the bytes of a are not there. Instead, printf gets some other bytes that happened to be in the register and converts those for printing.
  • The argument passing fails in other ways and corrupts your program.
  • The compiler catches the error during compilation and either warns you or refuses to compile your program, depending on settings.
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312