[Info-vax] VMS Cobol - GnuCOBOL

Dan Cross cross at spitfire.i.gajendra.net
Fri Mar 3 09:30:30 EST 2023


In article <k6e8a5Fu2e4U5 at mid.individual.net>,
bill  <bill.gunshannon at gmail.com> wrote:
>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.

Bill, do you understand that there are application domains where
people want well-defined modular arithmetic on unsigned types?
You seem intent on dismissing this as a valid use case, by
repeatedly that the results are "worthless."  As I pointed out
to you earlier in this thread, wrapping semantics can be very
useful.

>Go ahead, blame the language again.

Ok.  I blame the language for having confuing semantics, and I
blame compiler writer for exploiting that at the expense of
programmers.

	- Dan C.




More information about the Info-vax mailing list