How to deal with -wconversion warnings from gcc?

I am building my project with the warning sign GCC -Wconversion. (gcc (Debian 4.3.2-1.1) 4.3.2) on a 64-bit GNU / Linux OS / hardware. I find it useful in determining where I mixed types or lost clarity about which types should be used.

This is not very useful in most other situations that trigger his warnings, and I ask how I should deal with them:

enum { A = 45, B, C }; /* fine */ char a = A; /* huh? seems to not warn about A being int. */ char b = a + 1; /* warning converting from int to char */ char c = B - 2; /* huh? ignores this *blatant* int too.*/ char d = (a > b ? b : c) /* warning converting from int to char */ 

Due to the unexpected results of the above tests (cases a and c ), I also ask you to explain these differences.

Edit: And the add-in should include all this with (char) to prevent a warning?

Edit2: some additional cases (following from above):

 a += A; /* warning converting from int to char */ a++; /* ok */ a += (char)1; /* warning converting from int to char */ 

In addition, what I ask is subjective, and I would like to hear how other people deal with conversion warnings in cases where you think that some developers protect the removal of all warnings.

Yae:

One possible solution is to just use int instead of char right? Well, actually, this not only requires more memory, but also slower, as the following code indicates. Math expressions are only for warnings when building with -Wconversion . I assumed that the version using char variables will work slower than when using int due to conversions, but in my (64-bit system with two cores) the version of int slower.

 #include <stdio.h> #ifdef USE_INT typedef int var; #else typedef char var; #endif int main() { var start = 10; var end = 100; var n = 5; int b = 100000000; while (b > 0) { n = (start - 5) + (n - (n % 3 ? 1 : 3)); if (n >= end) { n -= (end + 7); n += start + 2; } b--; } return 0; } 

Pass -DUSE_INT to gcc to create an int version of the above snippet.

+4
source share
2 answers

When you say /* int */ , do you mean that this gives you a warning about this? I don't see any warnings at all in this code with gcc 4.0.1 or 4.2.1 with -Wconversion . The compiler converts these enums to constants. Since everything is known at compile time, there is no reason to generate a warning. The compiler can optimize all the uncertainty (the following Intel: 4.2.1):

  movb $45, -1(%rbp) # a = 45 movzbl -1(%rbp), %eax incl %eax movb %al, -2(%rbp) # b = 45 + 1 movb $44, -3(%rbp) # c = 44 (the math is done at compile time) movzbl -1(%rbp), %eax cmpb -2(%rbp), %al jle L2 movzbl -2(%rbp), %eax movb %al, -17(%rbp) jmp L4 L2: movzbl -3(%rbp), %eax movb %al, -17(%rbp) L4: movzbl -17(%rbp), %eax movb %al, -4(%rbp) # d = (a > b ? b : c) 

This does not include optimization. With optimization, it will calculate b and d for you at compile time and hard-code their final values ​​(if they really need them for something). The fact is that gcc has already developed that there can be no problem, because all possible values ​​fit into char .

EDIT: Let me make a few corrections. There may be an error in assigning b , and the compiler will never catch it, even if it is defined. For example, if b=a+250; , then it will be sure to overflow b , but gcc will not give a warning. This is because assigning a is legal, a is char , and it is your problem (not the compiler) to make sure the math is not overflowing at runtime.

+2
source

Perhaps the compiler can already see that all values ​​fit into char, so it does not bother the warning. I expected enum be resolved at the start of compilation.

0
source

All Articles