[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