Calculations between different types in C++

Started by
1 comment, last by Gamer Gamester 16 years ago
I have come upon the situation of doing calculations between different types in C++, and was wondering if some knowledgeable person could explain to me how C++ treats these interactions. I'll go a little into my situation, but I'm really just looking for a summary on the general topic (Yes, if applicable you may lecture me that I'm not following good coding practice or something, but I'd still like to know how C++ treats these situations). But my situation is the best way I can think of to explain what I want to know. So I'm storing some RGBA color values, and I do so with a color structure such as:
struct Color
{
  unsigned char r;
  unsigned char g;
  unsigned char b;
  unsigned char a;
};

Some would say I should just go ahead and use ints instead of unsigned chars, but I like it this way as it makes it clear from this simple code that the values can range from 0 to 255 (well, assuming 8-bit chars that is, which I am happily assuming). Now I'm creating some particular functions that do some calculations/transformations on these colors (such as mixing colors). To calculate the change that occurs, I am using ints, because I may need values outside of the 0 to 255 range (such as negative values). For example, if I want to get the result of a color_1 being mixed with color_2:

// Just setting the r values for simplicity
Color color_1;
color_1.r = 150;

Color color_2;
color_2.r = 40;

I use ints for the intermediary calculations because they may be negative or otherwise out of bounds. Assuming I'm applying the change to color_1, I calculate the change as so:

int change = color_2.r - color_1.r;   // Find out where color_2 is in relation to color_1
                                      // In this case the value is negative, so we can't
                                      // store in a unsigned char
change /= 2;          // Find out the midpoint between the colors
color_1.r += change;  // Apply the change

These first and last of the previous lines contain my questions: Question 1/Line 1: Any problems here? I assume not, as my understanding is that C++ will gracefully and silently promote the unsigned chars to ints. Question 2/Line 3: Any problems here? Here we are adding an int to an unsigned char. How does C++ handle this? Fine for my purposes? Will my compiler (g++ with the -Wall setting) complain with warnings? If so, is there a way to appease it? (I don't like seeing the warnings) Question 3: Also, do I need to do any bounds checking? I can't see any way that line 3 in the above code would result in a value > 255 or < 0, but am I missing something? I was debating replacing line 3 with:

if (color_1.r + change > 255)
{
  color_1.r = 255;
} else
{
  if ( color_1.r + change < 0 )
  {
    color_1.r = 0;
  } else
  {
    color_1.r += change;
  }
}

but it seems redundant. Your thoughts?
Advertisement
It all looks ok and the maths is safe.

The compiler will implicitly cast so as to handle type promotion and demotion for you; in the case of integers it'll do this by adding extra bits or truncating bits as necessary.

The compiler is, however, free to warn you of any possible loss of type information. If you explicitly cast between types then it'll supress the warning and also act as a reminder for you to be careful if you ever revist that code sometime in the future.

As it happens, by default, my compiler only seems to warn me when implicitly casting from long-to-char but not when implicitly casting from int-to-char; it only complains about int-to-char when I crank up the warning-level to maximum.
Thanks

This topic is closed to new replies.

Advertisement