Bjoern Milcke wrote:
Hi Stephan,
Bjoern Milcke wrote:
Hi Stephan,
I came across the following piece of code:
String a;
xub_StrLen n = 0;
n += a.Len();
This breaks on Windows (due to -werror). Because of the warning:
warning C4244: '+=' : conversion from 'int' to 'USHORT', possible
loss of data (in the last line of the fragment)
[...]
Does anybody have an idea what the problem is here?
By the holy standard, x += y where x, y are short works by promoting
x, y to int x', y', adding x' + y', converting int x' to short x''
and assigning x'' back to x. MSC chose to warn about this (about
the potentially lossy "converting int x' to short x''" part).
Where is that in the standard? Is there a C-Standard, or is this in
the C++-Standard. I couldn't find it.
C++ Standard, 5.17/7, 5.7/1, 5/9, 4.5/1.
5.17/7 just says that a += b is equivalent to a = a + b, except that a
is evaluated only once. This is only a proof that MSVC++ has a "bug"
that (short) = (short) + (short) is not a warning.
Why did you mention 5.7./1 and 5.9? Well, anyway, the conversion is
described in 4.5./1. I also found this but is says that rvalues of type
char and short *can* be converted to int. Well, it does not say that it
actually does. (And it doesn't say how big the probability is that a
compiler does this ;-) )
5.7/1: "The usual arithmetic conversions are performed for operands of
arithmetic or enumeration type." 5/9: "the usual arithmetic
conversions, which are defined as follows:"
I would interpret the wording in 5/9 (esp. footnote 54) and 4.5 to mean
that the conversions that can be performed are actually performed in
this context. (But you might want to check with comp.std.c++.)
Anyway, the warning is not really a big problem. It was nasty, but I can
live with it. However I would prefer to have a warning for:
(short) = (int)
but not for (short) = (short) op (short)
I usually don't use short (or sal_Int16) anyway, but especially if you
have typedefs like xub_StrLen, I really think this warning is a
nuisance. To avoid this warning I would have to cast all typedefs where
I don't know to what integral type they are currently defined (maybe
compiler-dependent).
sal_Foo a = 4, b = 3;
a = static_cast< sal_Foo >( a + b );
// instead of
a += b;
is just not so nice.
As I already wrote: I do not like these specific instances of C4244
either, but there are other instances of C4244 that are really useful.
Unfortunately, you can only have both or none.
I still see this conversion as compiler-internal and I just don't see
*any* benefit of having this warning (in this particular case). If it is
because the compiler cannot distinguish between a downcast that's in the
code and one that it enforced itself, well, fair enough. Then we have to
live with that.
Cannot follow you here. The downcasts in "short lvalue += ..." and
"static_cast<short>(...)" are both caused by the programmer, not by any
compiler internals.
-Bjoern
P.S.: When I was compiling some code for warning-freeness I really had
the situation for one directory:
unxlngi6.pro -> removed some warnings till being warning-free
unxlngi6 -> removed some more warnings
wntmsci10.pro -> some more new warnings to remove
wntmsci10 -> more warnings to remove
unxsols4.pro -> yet another warning not yet being covered
I know all compilers are different, but it would be nice to have a set
of warnings that is almost equal between compilers. Otherwise we are
forced to compile all platforms in our CWSes not only two of them.
We probably cannot do much about the non-pro/pro problem (as different
code is compiled in the two cases). If there are any compiler-specific
warnings that you would like to be switched off globally, so that the
warning sets are more uniform across compilers: just start a new thread
on this mailing list. (I at least found all the---differing---warning
sets useful in finding errors in the code, so I personally value "have
to build on three different compilers, but find errors early" higher
than "need only build on two different compiles, but might not find
errors.")
-Stephan
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]