简体   繁体   中英

How Are Typecasts in C Implemented?

From the perspective of an application programmer, typecasts just work. With some syntax, the unsigned representation of an integer can act as a signed integer value less than INT_MAX. What are the algorithms that perform these conversions and what are their time complexities? Are there dedicated items of modern Instruction Set Architectures that perform the conversions, or does the compiler know of a sequence of instructions? If there is platform dependence in how typecasts work internally, do these differences ever leak into the effects of a typecast?

The C language confuses two different processes under the same syntax of "type casting". The first is simply interpreting the same set of bits in two different ways. This is what happens, for example, when you cast a signed int to an unsigned int. Nothing actually changes, you just tell the compiler to interpret those bits in a different way. For example, the expression a < b might cause different code to be generated than for a < (unsigned)b , even though the cast itself does not actually do anything to the bits of b itself.

Likewise, a pointers to things can be cast to pointers to different things, but they're still just memory addresses, and the cast doesn't actually change anything other than how the compiler performs operations like pointer math and dereferencing.

The other unrelated thing that C mistakenly calls type casting is type conversion. If you have an int a , the expression (double)a will actually call a function to convert the integer to the equivalent double-precision floating point value. This involves considerable math. Converting among integer types generally leaves bits alone but adds extra bits: for example, if short a = 0x1234 , then (long)a will be 0x00001234 (whether the fill bits are 0s or 1s depends on signedness).

There isn't any code involved in the actual typecast. It's just reinterpreting the underlying bytes in a different way. All your typecast does is turn off the type checks in the compiler. Ie if you write:

unsigned int  uInt = UINT_MAX;
int           sInt = (int)uInt;

printf( "sInt = %d\n", sInt );

You get -1. That's because the underlying bytes are all set to 0xff, ie all bits are 1. If you look at 4 bytes expecting an unsigned int, that's 4294967295, if you look at 4 bytes expecting a signed int, the same bits are interpreted as -1.

The actual data in RAM doesn't change. However, the compiler generates different machine code instructions depending on whether it thinks these 4 bytes you've given it are signed or unsigned.

Similarly, if you specify a signed or unsigned int to printf(), but use the wrong format (ie print an unsigned int using %d, or a signed one using %u), printf is the place that interprets the bytes wrongly.

The advantage of C over assembler and raw machine code is that C actually keeps track of whether a variable should be considered signed or not, and doesn't force you to remember it, and even warns you when you get it wrong. Typecasts are just a signal to the compiler that such a "doing it wrong" case is actually correct, and the compiler should just trust you that you know what you're doing.

Mind you, in C++, things are different. Typecasting between C++ classes or assigning a subclass to a variable of the base class's type may actually generate code to adjust the pointer.

Update: As Alastair mentioned, that's not quite true: What I wrote is only 100% true if you typecast a pointer or types of the same size. For numeric types of different size, C will actually generate a tiny bit of code that eg truncates a floating point number like 4.5 into 4, or makes sure that if you typecast the char -1 into an int, it will move the bit that indicates the sign "up". That way, you still get -1, and not 255 (which would be the interpretation of the bits that make up -1 as a char when seen as an int).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM