Note the range of values that C / C ++ char takes

Introduction

I think that you know if it is a C plugrama, and although it is a new content, the content pointed out by the static analysis tool happened to be interesting, so I will generalize it and write it.

First sample code

#include <stdio.h>

#define VALUE 255

int main(void) {
  char c = VALUE;
  if (c == VALUE) {
    puts("TRUE");
  } else {
    puts("FALSE");
  }
  return 0;
}

What will be output when this program is executed?

In my environment (Ubuntu 16.04LTS, gcc (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.9) 5.4.0 20160609), it is as follows.

FALSE

It's not intuitive at all.

char is signed or unsigned processing system definition

Whether char is signed or unsigned depends on the processing system. (It's not like ʻintandlong` are always signed. It's confusing ...)

Typically

--Signed: [-128, 127] --Unsigned: [0, 255]

Will take the value of.

It was "signed" in the above environment. Therefore, 255 cannot be expressed.


char c = VALUE;

This makes the value of c``-1 (in the case of 8-bit and 2's complement representation).


  if (c == VALUE) {

This is the problem. The left side is char and the right side is ʻint. Due to the rules of C's integral promotion, c is converted to ** ʻint **. That is, ʻint's -1. The one on the right side is ʻint 255. Therefore, this conditional expression is false.

It's not a difficult story to look at, but if the place where this VALUE is defined and the place where it is actually used are far apart, it will be a problem that is quite difficult to follow.

By the way

With gcc, the options called -fsigned-char / -funsigned-char Yes, you can switch the behavior.

If you compile the above program with -funsigned-char, you will get the result of TRUE.

What should i do?

If you want to handle numbers in 8bit instead of characters or strings, use ʻint8_t / ʻuint8_t, at least sigined char / ʻunsigned char, and not char. Also, especially in C ++, defining constants as typed const ( constexpr`) constants rather than preprocessor macros is less likely to fall into the extra pitfalls.

Recommended Posts