Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting while using the '==' operator

Tags:

arrays

c

In my C program, I have a line where I am using the '==' operator, and the two operands are casted as char, like so:

char top_level_domain[sizeof(char) * 128];
...
if((char)top_level_domain[i] == ':' 
    || (char)top_level_domain[i] == '/')

Is this recommended/safe? If not, how should I go about checking the contents of a certain element in an array?

EDIT: added declaration and removed casts to the character literals

like image 432
dsplayer14 Avatar asked Aug 24 '13 19:08

dsplayer14


People also ask

How do you use a cast operator?

A cast is a special operator that forces one data type to be converted into another. As an operator, a cast is unary and has the same precedence as any other unary operator. const_cast<type> (expr) − The const_cast operator is used to explicitly override const and/or volatile in a cast.

What is type cast operator used for?

Cast operator: () A type cast provides a method for explicit conversion of the type of an object in a specific situation.

What is a cast operator in C#?

The operator used to perform cast operation in C# is parentheses. To perform a cast operation, the destination data type is explicitly written in parentheses before the value to be converted. An example for cast operation can be the conversion of a variable of double or float type to an integer type.


2 Answers

In general, it is more safe and effective to avoid casting when you can, because it allows the compiler to perform type checking. For example, spot the error:

// Let's pretend you forgot or mixed up the type here...
char **top_level_domain;
// ...
if ((char) top_level_domain[i] == (char) ':')
    ...

Or maybe...

char top_level_domain[sizeof(char) * 128];
...
// Whoops! forgot to type [i]
if((char)top_level_domain[i] == ':' 
    || (char)top_level_domain == '/')

Whoops! You forgot to dereference the pointer, you're getting garbage. The compiler would have given you a diagnostic message, but since you used a cast, the diagnostic message is gone.

Note: This will actually cause a diagnostic message on some compilers because char is narrower than char *, but if we were using size_t instead of char then there would be no narrowing, but it would still be an error.

Why use casts?

There are quite a few situations where the C "integer promotions" and "usual arithmetic conversions" can cause undesired behavior. For example,

size_t align_to_16_bytes(size_t x)
{
    // return x & ~15u; // WRONG
    return x & ~(size_t) 15u; // RIGHT
}

However, in general it will only cause problems when you are using types wider than int or when you are mixing signed and unsigned types that are at least as wide as int.

Newer languages such as Java and C# largely avoid this problem by only allowing widening implicit casts.

like image 90
Dietrich Epp Avatar answered Sep 21 '22 19:09

Dietrich Epp


The casts are "safe" but useless, and very bad style. Generally in C, anything that needs a cast is at best bad style, and more often, invoking undefined behavior, so the presence of casts in a source file is a "code smell" - an indication that the author probably did something wrong and that the reader needs to be extra careful looking for bugs.

Just remove the casts and your code will be perfectly fine.

like image 42
R.. GitHub STOP HELPING ICE Avatar answered Sep 18 '22 19:09

R.. GitHub STOP HELPING ICE