-2
#include <math.h>

int main(){

    signed char b = 32767;
    if (b){
        printf("YES");
    }
    else
        printf("NO");
}

I did not expect this to compile because signed char's range is [−127, +127] ?? I also tried to enter a value with 8 bits (12345678), that also compiled okay, 9 bits, however, caused my Avast antivirus to come up I thought the program hanged, but it compiled after a while.. My questions is shouldn't any value outside [−127, +127] be rejected by the compiler for a signed char data type?

mch
  • 9,424
  • 2
  • 28
  • 42
  • 1
    Maybe you ignore compiler warnings. – i486 Jun 20 '18 at 10:43
  • 2
    **Always enable compiler warnings, and heed them.** C (and C++) are very much languages that *allow* you to do "illegal" things if you insist... (You also didn't `#include ` there, for example, or wrote `int main( void )` as you should have done...) – DevSolar Jun 20 '18 at 10:43
  • ever heard of overflow? – Dumbo Jun 20 '18 at 10:55
  • Note: char range is [-128, 127] , not [-127, 127] as you said !!!!! in 2s complement the negative range is alwasy 1 more than positive range – Dumbo Jun 20 '18 at 10:56
  • Also, run the code through a debugger and see the actual value stored in 'b'. – Neil Jun 20 '18 at 10:57
  • @Saeid - char range can also be [0, 511], it [depends on your system](https://stackoverflow.com/a/6972551/597607). And who says it is using 2's complement? :-) – Bo Persson Jun 20 '18 at 11:09
  • I tried to run the code via Visual Studio.. The only option is command line visual c++ application, which I selected.. the code did not run, this could be because it is visuall c++ and my source code is in C – african_hermit Jun 20 '18 at 11:14
  • Also: [Is char signed or unsigned by default?](https://stackoverflow.com/questions/2054939/is-char-signed-or-unsigned-by-default) – Lundin Jun 20 '18 at 11:31
  • @BoPersson Ahhh you did find that 1% chance :) – Dumbo Jun 22 '18 at 13:45

2 Answers2

0

C is an old-school language. Don't say things like "I did not expect this to compile because...". In general, most C compilers try as hard as they can to compile something for you, even if it's dangerous. Don't say things like "Shouldn't any value outside the range be rejected by the compiler?". Most C compilers don't reject things just because they're a bad idea -- or even because they might not work.

Most modern compilers will, however, warn you about bad ideas, but even then, you may have to explicitly request such warnings, because in their default mode, the compilers may still be operating under the old-school assumption that the programmer knows what he is doing.

In C, overflow of unsigned types has guaranteed behavior -- arithmetic is always performed, in effect, modulo the size of the type. Although it's not guaranteed, most processors and most compilers implement the same sort of thing for overflow on signed types as well -- and there's probably a fair amount of code that depends on this. So that's another reason that compiler warnings about signed integer overflow aren't necessarily prominent.

With that said, though, I tried your code under two different compilers. One said "warning: overflow in implicit constant conversion", and the other said "warning: implicit conversion from 'int' to 'signed char' changes value from 32767 to -1".

If your compiler is not giving you warnings like these, you will either want to (a) make sure all warnings are enabled (either with a checkbox in a configuration settings dialog somewhere, or with a command-line option flag like -Wall), or (b) get a better compiler.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Strictly speaking, this isn't actually a signed integer overflow, but a conversion from a large signed integer to a smaller one. Still a bad idea of course, but not undefined, but impl.defined. An overflow would be `signed char b=0; b+=666;`. – Lundin Jun 20 '18 at 11:44
0

The C language allows you try to show a larger type into a smaller one, though how it will do so it is not well-defined and shouldn't be relied upon.

On this row signed char b = 32767; you attempt to store an int inside a signed char. What applies then is this part from the C standard (C11 6.3.1.3/3):

Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

So what will happen is not well-defined, but left to the system and compiler. On a typical 2's complement system, it is likely taking the binary value of 32767 = 0x7FFF, cutting off everything but the LS byte = 0xFF, then translating this as a signed char number, meaning decimal -1.

That being said, your code doesn't really make any sense and there's no use for such code in real applications, so good compilers will give you a warning for it.


The reason your anti-virus pops up is because anti-virus hates programmers. It spots that you try to change an executable (your own program's binary output). I would advise to disable/uninstall anti-virus on computers used for programming.

Lundin
  • 195,001
  • 40
  • 254
  • 396