From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 1014db,582dff0b3f065a52 X-Google-Attributes: gid1014db,public X-Google-Thread: 109fba,582dff0b3f065a52 X-Google-Attributes: gid109fba,public X-Google-Thread: 103376,bc1361a952ec75ca X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-08-22 13:34:27 PST Path: archiver1.google.com!newsfeed.google.com!newsfeed.stanford.edu!headwall.stanford.edu!news-out.nibble.net!hub1.nntpserver.com!cyclone-sjo1.usenetserver.com!usenetserver.com!newsfeeder.randori.com!newshub2.rdc1.sfba.home.com!news.home.com!news1.rdc1.bc.home.com.POSTED!not-for-mail From: kaz@ashi.footprints.net (Kaz Kylheku) Newsgroups: comp.lang.ada,comp.lang.c,comp.lang.c++ Subject: Re: Subtle Bugs, kudos Ada (was How Ada ...Red Code ...) References: <3B6555ED.9B0B0420@sneakemail.com> <87n15lxzzv.fsf@deneb.enyo.de> <3B672322.B5EA1B66@home.com> <4a885870.0108112341.7ce02ac0@posting.google.com> <3B834E5D.B0D26AB1@adaworks.com> <9lvsic$bet9s$1@ID-9852.news.dfncis.de> <9m0193$grs$1@bird.wu-wien.ac.at> <3B83F042.4CFB073D@home.com> Organization: Psycho-Neurotic Institute for the Very, Very Nervous Reply-To: kaz@ashi.footprints.net User-Agent: slrn/0.9.6.3 (Linux) Message-ID: Date: Wed, 22 Aug 2001 20:34:27 GMT NNTP-Posting-Host: 24.68.85.82 X-Complaints-To: abuse@home.net X-Trace: news1.rdc1.bc.home.com 998512467 24.68.85.82 (Wed, 22 Aug 2001 13:34:27 PDT) NNTP-Posting-Date: Wed, 22 Aug 2001 13:34:27 PDT Xref: archiver1.google.com comp.lang.ada:12290 comp.lang.c:76226 comp.lang.c++:84939 Date: 2001-08-22T20:34:27+00:00 List-Id: In article <3B83F042.4CFB073D@home.com>, Warren W. Gay VE3WWG wrote: >#define ACLIP 31744 >... >unsigned char >st_linear_to_Alaw( sample ) >short sample; > { > static const unsigned char exp_lut[128] = { ...snip... }; > int sign, exponent, mantissa; > unsigned char Alawbyte; > > /* Get the sample into sign-magnitude. */ > sign = ((~sample) >> 8) & 0x80; /* set aside the sign */ > if ( sign == 0 ) sample = -sample; /* get magnitude */ > if ( sample > ACLIP ) sample = ACLIP; /* clip the magnitude */ > ... Even before seeing the body of the function, I wonder why it's using old-style C. Even if there is a good reason for using old-style C, why is it using a promotable type for a parameter? The use of a promotable type means that if a correct function prototype is written for the function, it will have to use the promoted type, that is to say: unsigned char st_linear_to_Alaw (int sample); Lastly, why is the type short being used at all? The advantage of short is that it may provide a compact representation for a large array of integers, provided that a range no wider than -32767 to 32767 is required (the minimum range required by ANSI/ISO C for the type short). The way the sign is detected is completely braindamaged; it assumes that signed short is 16 bits wide, so that shifting it 8 bits to the right will cause the sign bit to land in position 7. Also, shifting right a signed quantity whose sign bit is 1 is implementation-defined; I think it's undefined in C99. What is wrong with, say: sign = (sample >= 0); /* 0 if negative */ Clearly, the programmer did not inspect that the function will produce the correct output value for every input. It was obviously not even tested or inspected what happens in inputs representing interesting partitions of the input space, such as -32768, -32767, 0 or 32767. The program is probably not accompanied by test cases consisting of files containing 16 bit linear samples and corresponding alaw files that are known to be correct. So we could say a number of things besides ``sox is written in the wrong programming language''. If this function is submitted for critique to comp.lang.c, the errors in it will be shaken out in an instant, and a maximally portable version will soon appear that will work on C implementations with unusual sizes of integral types, CHAR_BIT other than 8, and sign-magnitude or ones' complement representations for negative numbers. Try it! Would you hire the programmer who wrote this function, to work with you on a project in *any* programming language? If we are going to blame the programming language rather than the programmer then let's do it right. If the programming language is at fault, then it's because of the data representation. The program logic is correct over abstract integers; it fails due to the machine-oriented data represetation. So the problem is that the language allows the programmer to say ``use ony 16 bits and fail if the computation requires more''. That in itself is an usafe feature, regardless of whether the overflow is detected or not. Either way, the program fails to compute the result. Although detection in Ada is superior to ignoring the error in C, stopping the program on 16 bit overflow can still crash a rocket. If I ported the essence of the algorithm to Common Lisp (for instance), then it will just work. The additive inverse of -32768 will be happily computed as 32768. The undisciplined programmer won't be seduced into writing nonsense, such as artificially restricting the width of the computation. The integer type tries to approximate mathematical integers within the limitations of the machine resources. (defconstant *alaw-clip* 42) ;; substitute actual value here (defun st-linear-to-alaw (sample) (check-type sample integer) (let ((is-negative (< sample 0))) (setf sample (min (abs sample) *alaw-clip*)) ;; rest of the algorithm with a-law table lookup, etc... )) No bit manipulation tricks for detecting the sign, no 16 bit representation braindamage. The sample parameter could be a bignum, and it will work correctly. An alorithm can be described using pure, mathematical integers, and then turned into code directly, without worring about representation issues such as the limited range of integers. Prevention of such issues is superior to detection. So the bottom line is that whether you are programming in static languages like C or Ada, you are metaphorically carving clay tablets with with stone knives. These languages trade reliability and clarity for machine efficiency. Trivial differences among them are dwarfed by the differences between them and a truly high level language.