[Info-vax] VMS Cobol - GnuCOBOL
bill
bill.gunshannon at gmail.com
Fri Mar 3 07:42:44 EST 2023
On 3/3/2023 6:59 AM, Johnny Billquist wrote:
> Damn! I learned something new today...
>
> On 2023-03-01 15:54, Dan Cross wrote:
>> In article <ttnk0m$lg5$2 at news.misty.com>,
>> Johnny Billquist <bqt at softjar.se> wrote:
>>> On 2023-02-28 20:11, Dan Cross wrote:
>
> [...]
>
>>> You overcomplicated the whole explanation.
>>
>> Hmm.
>
> I was wrong. :-)
>
>>> Basically, if you multiply two numbers, and the result would be bigger
>>> than the types involved, the result is undefined.
>>
>> Well...no. _unsigned_ integer overflow in C is well-defined (it
>> has modular wrapping semantics; C11 sec 6.2.5 para 9).
>> Similarly, overflow of signed atomics is well-defined (C11 sec
>> 7.17.7.5 para 3), so this is not always true.
>
> I had actually missed that unsigned integers do have a defined overflow
> behavior. Thanks.
>
>>> In this case, the type
>>> is unsigned short. If the multiplication cause anything that don't fit
>>> into an unsigned short, then the result is undefined.
>>>
>>> And it's fairly easy to find two unsigned short numbers that when
>>> multiplied will give a result that don't fit into an unsigned short.
>>
>> The range of unsigned short has little to do with it, and
>> truncation of the result is fine too (again, defined to use
>> modular wrapping for unsigned types; C11 sec 6.3.1.3). The
>> problem is entirely due to the promotion to _signed_ int prior
>> to the multiplication. The fix, incidentally, is easy:
>>
>> unsigned short
>> mul(unsigned short a, unsigned short b)
>> {
>> unsigned int aa = a, bb = b;
>> return aa * bb;
>> }
>>
>> This is well-defined, even if the range of `unsigned short` is
>> the same as `unsigned int`, which is permitted by the standard.
>
> Right. My second error. It is allowed to promote a unsigned short to a
> signed int.
> I do feel that I don't entirely agree with that rule, but it's
> definitely written as such.
>
> Changing from unsigned to signed feels just as a freedom too much.
>
>>> It's really not that different from any other language. Some languages
>>> will throw an exception, others will just give some result that might or
>>> might not be meaningful. But there is no guarantee in almost any
>>> language of some kind of specific meaningful result. Try it in FORTRAN
>>> and see what you get there, or Cobol (or BASIC). :-)
>>
>> The issue, and the reason for the complex initial explanation,
>> is the subtle interaction between the implicit type promotion
>> rules, arithmetic, undefined behavior, and the freedom that UB
>> gives to compiler writers, which is pretty unique to C. Hence
>> why optimizing compilers often _appear_ to introduce bugs when
>> in fact they're performing perfectly legal transformations, and
>> turning off the optimizer can appear to "fix" the problem.
>
> Yup. You were right. Sorry that I had to go and read the spec again.
> Trusting my brain was obviously the wrong thing to do.
>
And it really doesn't matter whether the result is truncation,
conversion to signed int, wrap around, throwing an exception or
undefined. The answer is still going to be wrong and the calculation
worthless. So, what's the point? Fix the damn code.
Go ahead, blame the language again.
bill
More information about the Info-vax
mailing list