views:

280

answers:

3

I am currently dealing with code purchased from a third party contractor. One struct has an unsigned char field while the function that they are passing that field to requires a signed char. The compiler does not like this, as it considers them to be mismatched types. However, it apparently compiles for that contractor. Some Googling has told me that "[i]t is implementation-defined whether a char object can hold negative values". Could the contractor's compiler basically ignore the signed/unsigned type and treat them the same? Or is there a compiler flag that will treat them the same?

C is not my strongest language--just look at my tags on my user page--so any help would be much appreciated.

+1  A: 

This is compiler-dependent. For example, in VC++ there's a compiler option and a corresponding _CHAR_UNSIGNED macro defined if that option instructs to use unsigned char by default.

sharptooth
i figured we were using different compilers. that's a real problem, because installing a new one here could take forever, if not impossible.
geowa4
+3  A: 

Actually char, signed char and unsigned char are three different types. From the standard (ISO/IEC 9899:1990):

6.1.2.5 Types

...

The three types char, signed char and unsigned char are collectively called the character types.

(and in C++ for instance you have to (or at least should) write override functions with three variants of them if you have a char argument)

Plain char might be treated signed or unsigned by the compiler, but the standard says (also in 6.1.2.5):

An object declared as type char is large enough to store any member of the basic execution character set. If a member of the required source character set in 5.2.1 is stored in a char object, its value is guarantied to be positive. If other quantities are stored in a char object, the behavior is implementation-defined: the values are treated as either signed or nonnegative integers.

and

An object declared as type signed char occupies the same amount of storage as a ''plain'' char object.

The characters referred to in 5.2.1 are A-Z, a-z, 0-9, space, tab, newline and the following 29 graphic characters:

! " # % & ' ( ) * + , - . / :
; < = > ? [ \ ] ^ _ { | } ~

Answer

All of that I interpret to basically mean that ascii characters with value less than 128 are guarantied to be positive. So if the values stored always are less than 128 it should be safe (from a value preserving perspective), although not so good practice.

hlovdal
this chunk of code deals with images, so i suspect that there are more than 'A's and 'b's being stored there.
geowa4
problem was solved. apparently the possible values were 0-100 and we had received mixed versions. thank you for your help.
geowa4
A: 

I take it that you're talking about fields of type signed char and unsigned char, so they're explicitly wrong. If one of them was simply char, it might match in whatever compiler the contractor is using (IIRC, it's implementation-defined whether char is signed or unsigned), but not in yours. In that case, you might be able to get by with a command-line option or something to change yours.

Alternatively, the contractor might be using a compiler, or compiler options, that allow him to compile while ignoring errors or warnings. Do you know what sort of compilation environment he has?

In any case, this is not good C. If one of the types is just char, it relies on implementation-defined behavior, and therefore isn't portable. If not, it's flat wrong. I'd take this up with the contractor.

David Thornley