l i n u x - u s e r s - g r o u p - o f - d a v i s
L U G O D
 
Next Meeting:
November 4: Social gathering
Next Installfest:
TBD
Latest News:
Oct. 24: LUGOD election season has begun!
Page last updated:
2006 Jun 04 09:23

The following is an archive of a post made to our 'vox-tech mailing list' by one of its subscribers.

Report this post as spam:

(Enter your email address)
[vox-tech] C - passing chars and pointer to chars
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vox-tech] C - passing chars and pointer to chars



I've been learning Java's JNI API, and came across something about C that I
never knew.

There are 3 types of char:

   char
   signed char
   unsigned char

My understanding of the standard says that char can either be of type
"signed char" or "unsigned char"; it's implementation specific.  By
assigning "c = 255" I found that on my own platform (GNU/x86) a char is
implemented as a "signed char".  I think I remember reading that on Apple
platforms, it's implemented as an "unsigned char".

According to the gcc info page:

     Ideally, a portable program should always use `signed char' or
     `unsigned char' when it depends on the signedness of an object.
     But many programs have been written to use plain `char' and expect
     it to be signed, or expect it to be unsigned, depending on the
     machines they were written for.  This option, and its inverse, let
     you make such a program work with the opposite default.

*    The type `char' is always a distinct type from each of `signed
*    char' or `unsigned char', even though its behavior is always just
*    like one of those two.

char is a *distinct type* from "signed char" or "unsigned char".  That
surprised me.  So I did some experimentation and here's what I found.

Apparently, there's no problem assigning the different chars to each other.
The compiler does the automatic conversion:

   char          a = 0;
   signed char   b = 0;
   unsigned char c = 0;

   a = b; a = c;    // fine.
   b = a; b = c;    // fine.
   c = a; c = b;    // fine.

You can even pass the different types of char to functions that take
other types of char:

   void takesAChar( char x, signed char y, unsigned char z );

   takesAChar(a, b, c); takesAChar(a, c, b);  // fine.
   takesAChar(b, a, c); takesAChar(b, c, a);  // fine.
   takesAChar(c, b, a); takesAChar(c, a, b);  // fine.

What the compiler complains about is passing *pointers* to different
types of char:

   void takesACharPtr( char *x, signed char *y, unsigned char *z );

   takesACharPtr(&a, &b, &c); takesACharPtr(&a, &c, &b);  // warnings.
   takesACharPtr(&b, &a, &c); takesACharPtr(&b, &c, &a);  // warnings.
   takesACharPtr(&c, &a, &b); takesACharPtr(&c, &b, &a);  // warnings.

The warning is:

   pointer targets in passing argument foo of bar differ in signedness.

I'm trying to understand this.  I'm fairly sure the standard says that all 3
types of char must have the same width.  For pointer operations like:

   char s[] = "hello";
   unsigned char *cptr = s;
   ++cptr;
   putc( *cptr, stdout );

will correctly print "e" because "char" and "unsigned char" have the same
width, and when we add one to cptr, it points to the correct location in
memory.

What I'm getting at is this.  Because all the chars have the same width, it
doesn't matter WHAT kind of pointer you pass in to a function: char, signed
char, or unsigned char.  Pointer arithmetic just works, and it works because
they all have the same width.

On the other hand, the data is what gets mangled if you don't use the
correct type:

   char c = 255;
   printf("%d", c);

prints, as expected, -1.  Not 255.

So it seems to me that if the compiler complains about anything, it should
complain about passing a different type of char, not a different type of
char *.

Why does gcc 4 complain about passing different "char *" and not "char"?

And is this because of the standard or is it gcc specific?

Thanks!
Pete
_______________________________________________
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech



LinkedIn
LUGOD Group on LinkedIn
Sign up for LUGOD event announcements
Your email address:
facebook
LUGOD Group on Facebook
'Like' LUGOD on Facebook:

Hosting provided by:
Sunset Systems
Sunset Systems offers preconfigured Linux systems, remote system administration and custom software development.

LUGOD: Linux Users' Group of Davis
PO Box 2082, Davis, CA 95617
Contact Us

LUGOD is a 501(c)7 non-profit organization
based in Davis, California
and serving the Sacramento area.
"Linux" is a trademark of Linus Torvalds.

Sponsored in part by:
Appahost Applications
For a significant contribution towards our projector, and a generous donation to allow us to continue meeting at the Davis Library.