[Info-vax] VMS Cobol - GnuCOBOL
Johnny Billquist
bqt at softjar.se
Mon Mar 6 20:29:37 EST 2023
On 2023-03-06 23:07, Dan Cross wrote:
> In article <tu4pi3$nhe$1 at news.misty.com>,
> Johnny Billquist <bqt at softjar.se> wrote:
>> On 2023-03-03 13:42, bill wrote:
>>> Go ahead, blame the language again.
>>
>> No. I don't fully agree. The fact that unsigned types are defined to
>> have the wrapping behavior means that you could definitely do this
>> intentionally and for rather good reasons.
>>
>> But the type propagation rule here breaks that promise, which is what I
>> find *very* broken. I do consider it a error in the language
>> specification when this can happen.
>
> In fairness to C (!!), this only happens for types that are
> lower "rank" than `int`, where "rank" is defined in C11 sec
> 6.3.1.1. So if I start with an `unsigned int` and do my
> arithmetic, the implicit conversion to a larger signed type
> won't happen; the issue is when one starts with smaller types.
>
> Hence why the `mul` example is fixed by assignment to
> intermediate `unsigned int`s:
>
> unsigned short
> mul(unsigned short a, unsigned short b)
> {
> unsigned int aa = a;
> unsigned int bb = b;
> return aa * bb;
> }
>
> Of course, these rules are sufficiently obtuse, and so easy to
> accidentally misuse, that I have to agree with your assessment
> that this feels like a bug in the language.
Since unsigned and signed have more implications than just the ability
to contain negative numbers (in this case, the explicit definition that
arithmetic are done modulo the size of the storage for unsigned), I
believe it is inherently wrong to allow an unsigned integer to be
silently promoted to a larger signed integer.
Basically, since unsignedness implies more than just the range of
values, it can never be right to promote to a type with other
implications (signed in this case). Signed values inherently have other
properties, so they are not equal enough to be allowed to be moved
silently between.
I had totally missed that unsigned values are guaranteed to do modulo
arithmetic before. Although I've used it plenty, and find it extremely
useful, I always assumed it wasn't guaranteed by the language (and I was
just lucky), and I might even have seen examples where it broke for
optimized code. But I now suspect that was really when dealing with
signed values.
(I did at least once hit upon a compiler optimization which removed a
whole chunk of code because the compiler was moving between unsigned and
signed, and basically figured out the value could never be negative,
even though in reality it was. But it was all because of undefined
behavior, or implementation specific. So I've had to deal with these
wonders a few times already, and have become wary of assuming almost
anything...)
Johnny
More information about the Info-vax
mailing list