0

I am programing with TDD, where all warnings are converted to errors, and I am having a strange warning/error. I have a code like this

short int a = 0;
/* .... */
a = a + 2;

when I compile, I get this message

error: conversion to 'short int' from 'int' may alter its value [-Werror=conversion]

but if I change this line:

a = (short int)(a + 2);

the error dissapear. My question is, is really necessary to cast ALL my increments/decrements, or any basic operation? Why, in a operation where all the variables or constants are short int, the compiler is casting something to int? Even if I change the line to

a = a + (short int)1;

the error appears, so I think the problem is not the constant

I use

g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516

Wenfang Du
  • 8,804
  • 9
  • 59
  • 90
Alexi
  • 9
  • 3
  • Are you programming in C or C++? While they may share some syntax, they are really two *very* different languages, especially when it comes to semantics. It might not matter in this very specific case (besides the wording in the C and C++ specifications probably being different, so it might matter anyway), but please use only one language tag in the future. – Some programmer dude Jun 26 '18 at 13:30
  • @Someprogrammerdude, I used both languages because I am programming in C but checking with C++ (TDD is wrote in C++), but you are write that I am compiling with a C++ compiler – Alexi Jun 26 '18 at 13:36
  • 1
    Don't compile C with C++ compiler, as it will impose C++ rules on your C code. – Eugene Sh. Jun 26 '18 at 13:37
  • Good question, I don't get it either. In `a = a + (short int)1` a `short int` is added to another `short int` and the result is assigned to a `short int`, I don't see any `int`s here.. BTW the problem is the same in C and C++. – Jabberwocky Jun 26 '18 at 13:39
  • As mentioned by @EugeneSh. that's not really a good idea. As said, C and C++ are two very different languages with very different rules. There are many thing which are valid in C that are not valid on C++, and opposite. ***But*** when you say that you "am compiling with a C++ compiler", it might mean that you use e.g. `g++` to build source files ending with the `.c` suffix? Then that's okay, as `g++` will build those source file as C source files. Header file that you include in C++ source files are a different matter though. – Some programmer dude Jun 26 '18 at 13:40
  • @Jabberwocky anything smaller than an `int` is promoted to an `int` during arithmetic operations. – NathanOliver Jun 26 '18 at 13:41
  • I can understand that an operation will be promoted to int if the destination variable is an int or an auto, but in this case I use ALL my variables (including constant casting) as short int. I am sorry, but I cannot understand why, if the destination var is a short int, the operation is being promoted to an int, I think I must do an unnecessary casting. – Alexi Jun 26 '18 at 13:48
  • I have to use C code due to restrictions, but I want to check it under TDD, so it is necessary compile it with a C++ compiler. I think that's not the problem, I used to do it. – Alexi Jun 26 '18 at 13:50
  • Re: "all warnings are converted to errors" -- that's the source of the problem. Compiler writers don't know your code as well as you do, and should not be the judges of what's appropriate for your code and what's not. But unless the compiler is incredibly stupid, you should be able to do `a += 2;` without problems. If that doesn't work, turn off stupid warnings. – Pete Becker Jun 26 '18 at 13:56
  • I don't really see how the duplicate is answering the question. The C standard is stating under the [Usual arithmetic conversions](http://port70.net/~nsz/c/c11/n1570.html#6.3.1.8): *If both operands have the same type, then no further conversion is needed.* Is it different for C++? – Eugene Sh. Jun 26 '18 at 13:58
  • @EugeneSh. The link you provide says "Otherwise, the **integer promotions are performed on both operands**. Then the following rules are applied to the promoted operands: If both operands have the same type, then no further conversion is needed. [...]" (emphasis mine). It say that if the type is the same *after* integer promotion no further conversion is done. – Some programmer dude Jun 27 '18 at 05:46
  • @PeteBecker, the TDD philosophy is to convert all warnings to errors because "small warnings" can hide important, unexpected problems. The question is why I obtain a conversion warning (not overflow) when I use the same type of variable in the entire expression. – Alexi Jun 27 '18 at 07:00
  • @Alexi -- I'll bet your compiler doesn't give you a warning for `int i = something; i = i + 2;`, even though that could overflow, too. The fact that the possible overflow with `short` comes from a different route (promotion, valid addition, conversion back with possible loss of precision) doesn't change the consequences. If you're writing **correct** code you've considered the possibilities for overflow and dealt with them. Calling out operations with `short` as more suspect than operations with `int` puts the emphasis in the wrong place. – Pete Becker Jun 27 '18 at 11:59
  • @Someprogrammerdude Oh. That's a fine point... – Eugene Sh. Jun 27 '18 at 13:25
  • @PeteBecker the overflow is not the problem, just as you say. In fact, the operation `a++` doesn't return any warning, and as far as I know, it generates the same assembler code than `a = a+1`, but this last operation returns a warning. Likely I have a lack of knowleadge about this situation, since I cannot understand it – Alexi Jun 28 '18 at 07:04
  • @Alexi -- but `a++` poses **exactly the same risks** as `a = a + 1`. Relying on a compiler writer's judgment about good style is not a substitute for understanding what your code is doing. Making cosmetic changes in order to silence a warning is not the same as writing correct code. Turning all warnings into errors is a waste of time if it becomes an end in itself. "The TDD philosophy", as you describe it, replaces sound engineering with slogans. – Pete Becker Jun 28 '18 at 11:07
  • @PeteBecker I am totally agree with you, the risk in both operations is exactly the same: precisely for that reason I don't understand why the compiler returns a warning in the first case but not in the second one, why the first case is being promoted to int, since it is not necessary. In any case, I appreciate very much your comments, thanks a lot! – Alexi Jun 28 '18 at 12:39
  • @Alexi -- the reason `a = a + 1` promoes to `int`, at the most superficial level, is that that's what the language definition says happens. `short` and `char` (and their signed and unsigned variants) are second-class citizens when arithmetic is involved; they **always** get promoted to `int`. So `a + 1` has type `int` (and would, even if it had been written `a + 1s` so that it involved only `short` values). `a = a + 1` requires a conversion from the `int` value on the right-hand side back to `short`; the compiler generates code for the conversion, and that triggers the warning. – Pete Becker Jun 28 '18 at 13:24

0 Answers0