Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.datemas.de!weretis.net!feeder4.news.weretis.net!news.mixmin.net!aioe.org!.POSTED!not-for-mail From: "Rod Pemberton" Newsgroups: comp.lang.forth Subject: Re: Why I like Forth Date: Sun, 23 Nov 2014 14:33:33 -0500 Organization: Aioe.org NNTP Server Lines: 55 Message-ID: References: <87d988fc-26c2-492c-8e51-f0ede5758a69@googlegroups.com> NNTP-Posting-Host: i+Urkql2cL38hhKqzSWEjg.user.speranza.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Opera Mail/12.16 (Linux) X-Notice: Filtered by postfilter v. 0.8.2 Xref: csiph.com comp.lang.forth:34584 On Sun, 23 Nov 2014 05:45:12 -0500, wrote: > $ echo "int main (void) { char a=-128; return printf("%d",abs(a)); }" > > a.c; gcc a.c 2&>err; ./a > 128 This C code is NOT the same as the Forth code ... > I do understand this result and that of C [...] Do you? Do you truly understand the C result? 1) You used the stack in Forth to solve the problem. You didn't use VARIABLE in Forth to create a variable, nor did you create a stack in C to use a stack in C. I.e., these examples aren't the same, but are similar. 2) You didn't bitwise-and '&' the variable 'a' with 0xFF, i.e., abs(a&0xFF), as you did in your Forth examples. If you had done so, or if you correct your code to do so, there will be two errors in C: 2a) abs() takes an 'int'. Without a cast to 'int', C does a type conversion from 'char' to 'int', sometimes referred to as an "implicit cast". This conversion is "value preserving". For signed values, that means there is a representation change since one bit of the integer is used for the sign. The position of the sign-bit will move due to the conversion, since the sizeof(char) in bits must be at least 8-bits while sizeof(int) in bits must be at least 16-bits. I.e., if sizeof(char) in bits is 8-bits and sizeof(int) in bits is 16-bits, then the integer's sign-bit would move from bit 7 to bit 15 to preserve the signed integer value, and similarly to bit 31 for 32-bits. This is not a problem with your code as it is. But, it is a problem if you were to correct your code to bitwise-and the variable 'a' with 0xFF, as you did in your Forth examples. The 0xFF would clear out the sign-bit in ALL cases prior to the abs() call, i.e., abs() would not do anything since it would always be passed an unsigned value. 2b) You've assumed the sizeof(char) is 8-bits, hence the $FF AND in the Forth examples. The sizeof(char) in bits for C may be larger than 8-bits. 8-bits is a minimum without any maximum. If you fix your code to bitwise-and 'a' with 0xFF to match what you did in the Forth examples, then the code would clear the sign-bit for char's of 9-bits, 10-bits, 11-bits, ... etc, but would preserve the sign-bit for 8-bit chars. I.e., it would work for 8-bits, but fail for larger bit sizes. You didn't do the bitwise-and in C, which is good. But, the C code is no longer the functionally the same as the Forth code. So, your C code is correct, but it doesn't match the Forth. The correct way to match the Forth is to create an array of int's in C and use it as a stack. Rod Pemberton