How to enable compiler warning when comparing char and unsigned char? (2024)

Tags:

c

gcc

unsigned

signed

compiler-warnings

take for example the following C code :

int main(int argc, char *argv[]){ signed char i; unsigned char count = 0xFF; for (i=0; i<count;i++) { printf("%x\n", i); } return 0;}

This code runs in an infinite loop, even if I compile it as follows :

# gcc -Wall -Wpedantic -Wconversion -Wsign-compare -Wtype-limits -Wsign-conversion test.c -o test

Does someone know for a compiler flag that should warn about those kind of issues ?

Just to be clear, I'm not asking 'why is get an infinite loop', but to know if there's a way to prevent it using a compiler or static analysis ?

How to enable compiler warning when comparing char and unsigned char? (1)889

How to enable compiler warning when comparing char and unsigned char? (2)asked Oct 31 '16 11:10

sagi

People also ask

Is char the same as unsigned char?

A signed char is a signed value which is typically smaller than, and is guaranteed not to be bigger than, a short . An unsigned char is an unsigned value which is typically smaller than, and is guaranteed not to be bigger than, a short .

Is char default signed or unsigned?

In the book "Complete Reference of C" it is mentioned that char is by default unsigned.

Why do we need signed and unsigned char in C?

Signed char and unsigned char both are used to store single character. The variable stores the ASCII value of the characters. For an example if 'A' is stored, actually it will hold 65. For signed char we need not to write the signed keyword.

What is meant by signed and unsigned char in C?

The XDR standard defines signed integers as integer. A signed integer is a 32-bit datum that encodes an integer in the range [-2147483648 to 2147483647]. An unsigned integer is a 32-bit datum that encodes a nonnegative integer in the range [0 to 4294967295].

3 Answers

The flag -Wconversion won't catch the error, because both operands in the comparison: i<count, get promoted to int using integer promotions.

There is no flag in gcc that would catch this.

That aside, the behavior of your code is undefined, because variable i overflows, when it has the value 0x7F and is incremented: i++.

If you want to iterate up to some value, make sure the type you're using can represent that value.

How to enable compiler warning when comparing char and unsigned char? (3)57

How to enable compiler warning when comparing char and unsigned char? (4)answered Oct 20 '22 04:10

2501

i is a signed char, incrementing it beyond SCHAR_MAX has an implementation defined effect. The computation i + 1 is performed after promotion of i to int and it does not overflow (unless sizeof(int) == 1 and SCHAR_MAX == INT_MAX). Yet this value is beyond the range of i and since i has a signed type, either the result is implementation-defined or an implementation-defined signal is raised. (C11 6.3.1.3p3 Signed and unsigned integers).

By definition, the compiler is the implementation, so the behavior is defined for each specific system and on x86 architectures where storing the value results in masking the low-order bits, gcc should be aware that the loop test is definitely constant, making it an infinite loop.

Note that clang does not detect the constant test either, but clang 3.9.0 will if count is declared as const, and it does issue a warning if i < count is replaced with i < 0xff, unlike gcc.

Neither compiler complains about the signed / unsigned comparison issue because both operands are actually promoted to int before the comparison.

You found a meaningful issue here, especially significant because some coding conventions insist on using the smallest possible type for all variables, resulting in such oddities as int8_t or uint8_t loop index variables. Such choices are indeed error-prone and I have not yet found a way to get the compiler to warn the programmer about silly errors such as the one you posted.

How to enable compiler warning when comparing char and unsigned char? (5)42

How to enable compiler warning when comparing char and unsigned char? (6)answered Oct 20 '22 04:10

chqrlie

Since i is a signed char, its value ranges from -128 to 127 typically. Whereas count being an unsigned char is assigned the value 255 (0xFF).

Inside the loop, when i value gets to 127 and is incremented again, it never reaches 128 and gets to -128 and then gets again to 127 and then again rolls over to -128, and so on. The value of i will be forever less than the value of count inside the loop and so the loop can never terminate!

This is happening because of the overflow of the data type and care must be taken to critically examine the expressions where automatic type coercions may take place as they will not issue any warning.

EDIT:From the GCC documentation,

-Wconversion:Warn for implicit conversions that may alter a value.

Here, we are getting inconsistency due to comparison and not assignment.

How to enable compiler warning when comparing char and unsigned char? (7)39

How to enable compiler warning when comparing char and unsigned char? (8)answered Oct 20 '22 03:10

skrtbhtngr

Sign in toComment

Related questions

How to compile C code with the "Unix networking programming book" library?

How to change Project Character Set in JetBrains Clion

How future-proof is it to force a structure alignment with `__attribute__((packed,aligned(N)))`?

C - Formatting String size with special characters

What data type should be used for a probability? [closed]

With ASLR turned on, are all sections of an image get loaded at the same offsets relative to the image base address every time?

Keyboard interrupt handler not working in system iso

AVR C compilers behavior. Memory management

What does %r mean in kernel printf formats?

How to write generic #define macro in C and write less code

Passing an array from a thread

What does the C standard mean by "converted to its semantic type" for the floating-point macros?

Is there a way to assign a unique number to a type in C?

Calling a C function with a double pointer output parameter using CGo

What's the proper way to use different versions of SSE intrinsics in GCC?

What does -fwrapv do?

Are all functions in C/C++ assumed to return?

Why does 'typeof enum constant' generate a warning when compared to a variable of enum type?

Why do some experienced programmers write comparisons with the value before the variable? [duplicate]

Convert physical address to virtual in Linux and read its content

How to enable compiler warning when comparing char and unsigned char? (2024)

References

Top Articles
Latest Posts
Article information

Author: Msgr. Benton Quitzon

Last Updated:

Views: 5691

Rating: 4.2 / 5 (63 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Msgr. Benton Quitzon

Birthday: 2001-08-13

Address: 96487 Kris Cliff, Teresiafurt, WI 95201

Phone: +9418513585781

Job: Senior Designer

Hobby: Calligraphy, Rowing, Vacation, Geocaching, Web surfing, Electronics, Electronics

Introduction: My name is Msgr. Benton Quitzon, I am a comfortable, charming, thankful, happy, adventurous, handsome, precious person who loves writing and wants to share my knowledge and understanding with you.