Tu Do
Tu Do

Reputation: 339

What does (int)(unsigned char)(x) do in C?

In ctype.h, line 20, __ismask is defined as:

#define __ismask(x) (_ctype[(int)(unsigned char)(x)])

What does (int)(unsigned char)(x) do? I guess it casts x to unsigned char (to retrieve the first byte only regardless of x), but then why is it cast to an int at the end?

Upvotes: 7

Views: 1563

Answers (4)

Peter
Peter

Reputation: 36597

(unsigned char)(x) effectively computes an unsigned char with the value of x % (UCHAR_MAX + 1). This has the effect of giving a non-negative value (between 0 and UCHAR_MAX). With most implementations UCHAR_MAX has a value of 255 (although the standard permits an unsigned char to support a larger range, such implementations are uncommon).

Since the result of (unsigned char)(x) is guaranteed to be in the range supported by an int, the conversion to int will not change value.

Net effect is the least significant byte, with a positive value.

Some compilers give a warning when using a char (signed or not) type as an array index. The conversion to int shuts those compilers up.

Upvotes: 11

Bathsheba
Bathsheba

Reputation: 234715

A cast to unsigned char safely extracts the least significant CHAR_BITs of x, due to the wraparound properties of an unsigned type. (A cast to char could be undefined if a char is a signed type on a platform: overflowing a signed type is undefined behaviour in c). CHAR_BIT is usually 8.

The cast to int then converts the unsigned char. The standard guarantees that an int can always hold any value that unsigned char can take.

A better alternative, if you wanted to extract the 8 least significant bits would be to apply & 0xFF and cast that result to an unsigned type.

Upvotes: 2

AndersK
AndersK

Reputation: 36082

The unsigned char-cast is to make sure the value is within the range 0..255, the resulting value is then used as an index in the _ctype array which is 255 bytes large, see ctype.h in Linux.

Upvotes: 2

Ely
Ely

Reputation: 11162

I think char is implementation dependent, either signed or unsigned. So you need to be explicit by writing unsigned char, in order not to cast to a negative number. Then cast to int.

Upvotes: 0

Related Questions