[vox-tech] C - passing chars and pointer to chars
Peter Jay Salzman
p at dirac.org
Fri Jun 2 10:27:04 PDT 2006
Hi Mike,
It appears to be a gcc4 thing. Happens even with no warnings switched on.
Doesn't appear to happen at all with gcc3.
Pete
On Fri 02 Jun 06, 10:19 AM, Michael Wenk <wenk at praxis.homedns.org> said:
> Pete,
>
> I am not sure if this is the full story or not(or whether its standard or not,
> this is just my opinion. YMMV) Its pretty rare in my experience to pass by
> value chars(either unsigned or signed), I mean look at functions like memset
> and strchr, they take ints for what usually is a char. So when you pass
> strings around(which are pointers to character), it probably concerns itself
> more with the signedness. I am curious how you compiled? Did you
> have -Wall ? If not, does that change things?
>
> mike
>
> On Friday 02 June 2006 08:31 am, Peter Jay Salzman wrote:
> > 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 at lists.lugod.org
> > http://lists.lugod.org/mailman/listinfo/vox-tech
> _______________________________________________
> vox-tech mailing list
> vox-tech at lists.lugod.org
> http://lists.lugod.org/mailman/listinfo/vox-tech
--
Peter Jay Salzman, Ph.D.
http://www.dirac.org/p p at dirac.org
pgp: B9F1 6CF3 47C4 7CD8 D33E 70A9 A3B9 1945 67EA 951D
"Coffee... I've conquered the Borg on coffee!"
-- Kathryn Janeway on the virtues of coffee
More information about the vox-tech
mailing list