XPost: comp.lang.c
On 28/10/2018 10:42, jacobnavia wrote:
This warning should notify the user that a constant doesn't fit into the expected type.
For instance
char m = 476;
or
double s = 1e456;
This happens also when assigning the result of a function, and in other situations, for instance
_Bool h = 6;
Gcc however will warn sometimes, sometimes not.
Compiling the following program:
char s = 654;
_Bool h = 8;
float fnf(void) { return 1e145; }
_Bool error_p(int a)
{
int m = a != 0;
if (a != 0)
return 7;
return a != 0;
}
will produce the following warnings:
foo.c:1:10: warning: large integer implicitly truncated to unsigned type [-Woverflow]
char s = 654;
^~~
foo.c: In function ‘error_p’:
foo.c:7:6: warning: unused variable ‘m’ [-Wunused-variable]
int m = a != 0;
It detects that the assignment to a char of the number 654 will overflow
but issues an otherwise incomprehensible warning:
"integer implicitely truncated to unsigned type"...
That is not incomprehensible to me, but there is always scope for
improving the helpfulness of error messages in a compiler - this is
something gcc has worked on greatly in past years. So try it again with
a newer gcc - gcc 8 gives:
<source>:8:10: warning: overflow in conversion from 'int' to 'char'
changes value from '654' to '-114' [-Woverflow]
char s = 654;
^~~
This should be clearer, I think.
Well at least it says something.
No warnings will be issued for the overflow of assigning a float with a constant that is beyond the dynamic range of the type, nor it will issue
a warnçing when assigning 7 to a bit...
Why is this?
It is - arguably unfortunately - the way C works.
When you write something like "char s = 654;", the interpretation is
that "654" is an integer constant (it will be of type "int") which is
then assigned to the char "s". It is perfectly legal to assign such a
value - the conversion is implementation-defined (or can raise a signal)
if plain char is a signed type, or done as modulo wrap-around if it is
an unsigned type. (The gcc implementation-defined behaviour for
assigning to signed integer types is always modulo wrap-around too.)
It is all legal C and a conforming compiler should not reject any of the
code above (but it can warn about it). By default, gcc warns about the overflow in assigning 654 to a char - the relevant warning option
"-Woverflow" is enabled by default.
The "-Wconversion" warning will warn about the conversion in "fnf" to
+Inff. I would have liked -Wconversion to be part of -Wall or at least -Wextra, but it is not. (I like gcc, but I am not going to say it is
perfect!)
Conversion of something other than 0 or 1 to a boolean is so common in
code that there is no warning for it. I think it might be reasonable to
have a warning for cases like this initialisation or other uses of a
constant expression converted to a boolean, but you would not want it by default.
Lcc-win issues a warning for all those cases. I am reviewing the
warnings of lcc-win and I would like to know if other compilers besides
gcc have the same behavior.
Warnings are good - just be careful that warnings can give false
positives on legal code.
The compiler flags I used were:
clang gives the same warnings.
<
https://godbolt.org> is your friend here.
gcc -Wall -Wpedantic
If you want to test more solid warning capabilities, you need more
flags. I'd add "-Wextra" to this, and in this particular case
"-Wconversion" is key.
gcc has a /lot/ of warning flags and it is not easy to know which would
be good to use. But for your research here, I'd recommend reading the
relevant page:
<
https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html>
I am sure it will give you some new ideas.
Note that clang has the same behavvior as gcc but the wording of the
warnings is much clearer:
tretbool.c:1:10: warning: implicit conversion from 'int' to 'char'
changes value from 654 to -114 [-Wconstant-conversion]
char s = 654;
Still, no warnings are issued for the other cases.
(Newer versions of gcc have pretty much the same wording.)
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)