Pelles C forum

Pelles C => Bug reports => Topic started by: Robert on August 02, 2012, 09:55:13 AM

Title: CHAR - UNSIGNED CHAR Problem
Post by: Robert on August 02, 2012, 09:55:13 AM
The attached program, when it is compiled with Pelles C Version 7.0, has different output than when it is compiled with Version 6.5.0 RC4.

Robert Wishlaw
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: AlexN on August 02, 2012, 10:55:56 AM
Yes, it seems that version 6.50 rc4 ignores the switch for unsigned char (and uses it always).
But I assume that Pelle will never correct this in the old version and the new seems to work correct. ;)
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: jcfuller on August 02, 2012, 01:14:54 PM
Both gcc 4.61 and tc display the same results (unsigned char) as 6.5 ???

James
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: AlexN on August 02, 2012, 01:58:58 PM
Both gcc 4.61 and tc display the same results (unsigned char) as 6.5 ???
Wenn many make something wrong in the same way, it becomes not correct. ;)
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: jcfuller on August 02, 2012, 05:24:37 PM
I just tried Borland c++ 5.5.1 and VS 2010 and both produce unsigned char.

James
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: CommonTater on August 02, 2012, 05:58:13 PM
Haven't tested this but... Could the problem be that you are casting your variables to UINT when testing?

Code: [Select]
if((UINT) a[counter]>= (UINT) b[counter])

Try it without the typecasts in there... what happens then? 
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: jcfuller on August 02, 2012, 06:18:34 PM
Tater,
  The problem as I see it is not the code but every compiler I have tested gives the same results except Pelles 7.

I use many different compilers with bcx and PellesC was my first choice for "c" code; but ver 7 is not consistent with any others including PellesC 6.5.

James
 
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: Robert on August 02, 2012, 07:40:46 PM
Haven't tested this but... Could the problem be that you are casting your variables to UINT when testing?

Code: [Select]
if((UINT) a[counter]>= (UINT) b[counter])

Try it without the typecasts in there... what happens then?

The str_cmp function is used in many places in the BCX translator to compare strings containing unsigned chars. This function no longer works as expected and does not work in the same manner as it has for years.

The program attached to the original post is a simple example to demonstrate the problem. The problem is the inconsistent result between Pelles C 6.5.0 RC4 and Pelles C 7.0. That is the only problem.

Robert Wishlaw
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: CommonTater on August 03, 2012, 12:12:59 AM
Tater,
  The problem as I see it is not the code but every compiler I have tested gives the same results except Pelles 7.

I use many different compilers with bcx and PellesC was my first choice for "c" code; but ver 7 is not consistent with any others including PellesC 6.5.

Hello James and Robert...
 
I'm not saying it isn't a bug.  I was only suggesting a simple experiment to help track down the problem.
 
That said...
 
I tried a very simple test here and it would appear that in logical comparisons, including == the compiler's internal logic sees no difference between signed and unsigned char and clearly -32 and 224 are not the same (although they share the same bit pattern).
 
Typecasting did nothing for me.  It was not until I actually assigned the char values to int variables that I got the correct answers. 
 
But, something very interesting happened while playing with the project... if I turned off the optimizer I suddenly got the right answers... 
 
A Demo project is attached, try compiling it without optimizations then with any optimization you choose... look at your answers. The attached screen snip show both results... the top one is optimizations off, the bottom one is set to maximize speed.
 
So it would appear this is an optimization problem that can be fixed by bracketing your function...
Code: [Select]

#pragma optimize(none)

// your function here
 
#pragma optimize(speed)  // size etc.

Hope that helps....
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: Robert on August 03, 2012, 01:17:41 AM
Tater,
  The problem as I see it is not the code but every compiler I have tested gives the same results except Pelles 7.

I use many different compilers with bcx and PellesC was my first choice for "c" code; but ver 7 is not consistent with any others including PellesC 6.5.

Hello James and Robert...
 
I'm not saying it isn't a bug.  I was only suggesting a simple experiment to help track down the problem.
 
That said...
 
I tried a very simple test here and it would appear that in logical comparisons, including == the compiler's internal logic sees no difference between signed and unsigned char and clearly -32 and 224 are not the same (although they share the same bit pattern).
 
Typecasting did nothing for me.  It was not until I actually assigned the char values to int variables that I got the correct answers. 
 
But, something very interesting happened while playing with the project... if I turned off the optimizer I suddenly got the right answers... 
 
A Demo project is attached, try compiling it without optimizations then with any optimization you choose... look at your answers. The attached screen snip show both results... the top one is optimizations off, the bottom one is set to maximize speed.
 
So it would appear this is an optimization problem that can be fixed by bracketing your function...
Code: [Select]

#pragma optimize(none)

// your function here
 
#pragma optimize(speed)  // size etc.

Hope that helps....

Hi Tater:

Thank you for you interest and comments. Yes, and I am sorry that I forgot to mention it, it is a problem that occurs when the optimizer flags are set to /Ot or /Ox.  Your suggestion for bracketing the function with pragmas is useful but I think that this problem may have ramifications beyond this case. I wonder if John Findlay's and Donyuan's Bug Report complaints may have the same root cause.

The BCX translator works producing C code that will compile with several compilers. The signedness of char is not specified in the C Standard but is dependent on the implementation of char in the compiler. Some compilers have signed char as the default while others use unsigned char. The BCX str_cmp function is an attempt to have a generic function that will work independent of the char default for the compiler.

Robert Wishlaw
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: CommonTater on August 03, 2012, 02:17:56 AM
Thank you for you interest and comments. Yes, and I am sorry that I forgot to mention it, it is a problem that occurs when the optimizer flags are set to /Ot or /Ox.  Your suggestion for bracketing the function with pragmas is useful but I think that this problem may have ramifications beyond this case. I wonder if John Findlay's and Donyuan's Bug Report complaints may have the same root cause.

:D Shhh... don't tell anyone I said this, but Pelle's optimizer is broken. There have been several problems attributed to it over the past couple of versions.  Since we are not in an updating cycle right now, it could be some time before it's fixed, hense the workaround...  If you are concerned about errors in other compilers because of the pragmas you can always do this...
Code: [Select]
#ifdef __POCC__
#pragma optimize(none)
#end if
 
// your stuff
 
 
#ifdef __POCC__
#pragma optimize()
#end if

Yes, it's a hack, but it should hold you till the next update cycle.  (Details are in the help file)
 
 
Quote
The BCX translator works producing C code that will compile with several compilers. The signedness of char is not specified in the C Standard but is dependent on the implementation of char in the compiler. Some compilers have signed char as the default while others use unsigned char. The BCX str_cmp function is an attempt to have a generic function that will work independent of the char default for the compiler.

Understood... I realize this complicates things... but I know of only one other solution, until the optimizer is fixed : If you are somehow invoking POCC to compile BCX output, you could just remove the optimizations from the command line.
 
FWIW... I've done some testing of various code I've written with Optimizations on and off and frankly I don't see enough difference to make enabling them worthwhile.  Of course an optimizer is only a benefit when the optimizations actually work. :D   
 
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: AlexN on August 03, 2012, 09:27:44 AM
The program attached to the original post is a simple example to demonstrate the problem. The problem is the inconsistent result between Pelles C 6.5.0 RC4 and Pelles C 7.0. That is the only problem.
In the IDE of Pelles C 7.0 you have the option to switch between unsigned (-J) and signed char (this is the default value). If you choose here unsigned you get the same result like the from the other compiler.
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: TimoVJL on August 03, 2012, 03:31:55 PM
There is a real problem with v 7.0.
Code: [Select]
#include <stdio.h>

void test1(char a, char b)
{
if ((unsigned char)b >= (unsigned char)a) puts("unsigned char");
else puts("signed char");
}

#pragma optimize(none)
void test2(char a, char b)
{
if ((unsigned char)b >= (unsigned char)a) puts("unsigned char");
else puts("signed char");
}
#pragma optimize()

int main(int argc, char **argv)
{
char a = 122, b = 166;
test1(a, b);
test2(a, b);
return 0;
}
returns
signed char
unsigned char
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: CommonTater on August 03, 2012, 05:31:20 PM
There is a real problem with v 7.0.

So it would seem... it appears that with optimizations on, typecasts are being ignored as are the types of the variables.
 

The optimizer and library functions are very important to the creation of properly functioning code. Between this and the problem with memmove() I wonder if we could convince Pelle to update POCC and issue a replacement file we can drop into our installations... 
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: Pelle on September 01, 2012, 08:48:14 PM
I will have to analyze this first, before saying anything more...
Title: Re: CHAR - UNSIGNED CHAR Problem
Post by: Robert on September 29, 2012, 08:08:17 AM
There is a real problem with v 7.0.
Code: [Select]
#include <stdio.h>

void test1(char a, char b)
{
if ((unsigned char)b >= (unsigned char)a) puts("unsigned char");
else puts("signed char");
}

#pragma optimize(none)
void test2(char a, char b)
{
if ((unsigned char)b >= (unsigned char)a) puts("unsigned char");
else puts("signed char");
}
#pragma optimize()

int main(int argc, char **argv)
{
char a = 122, b = 166;
test1(a, b);
test2(a, b);
return 0;
}
returns
signed char
unsigned char

This problem has not been fixed in Version 7.0r.

Robert Wishlaw