l i n u x - u s e r s - g r o u p - o f - d a v i s
Next Meeting:
July 7: Social gathering
Next Installfest:
Latest News:
Jun. 14: June LUGOD meeting cancelled
Page last updated:
2006 Jun 02 12:35

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)
Re: [vox-tech] C - passing chars and pointer to chars
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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

On Fri, Jun 02, 2006 at 11:31:43AM -0400, Peter Jay Salzman wrote:
>    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.

char is a distinct type from both signed and unsigned char.  Not only
that, but it is also considered "incompatible" with the other types,
even though it is required to have precisely the same representation as
one of the other two.

The actual fact that it warns about pointers to chars of different
/signedness/ is fairly misinformative (as then, it shoud not complain
when you swap &a and &b only).

> 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.

Pointers to incompatible types are not guaranteed to be represented the
same way, even though in practice they are. /All/ pointer types must be
convertible to and from a pointer to any character type, and used as
such, so this makes it all the more likely that they will be represented
the same.

Irregardless, the Standard does /require/ that a warning be given when
you try to do this.

> 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 *.

Perhaps; but assigning between different integer types does not require
a diagnostic, even when overflow occurs (as when you assign 255 to an
8-bit signed char).

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

Assignment between different integer types happens all the time. It's
not always well-defined (for instance, assigning 255 to an 8-bit signed
char invokes "undefined" behavior, and can cause nasal daemons to fly
out your nose, as far as the Standard is concerned).

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

Standard. gcc3 probably didn't complain because 4 has gotten a bit more
pedantic. GCC does not issue all required diagnostics, unless you also
throw in a -pedantic flag. To get the maximum diagnostics, I usually
invoke using -W -Wall -ansi -pedantic (if it's C90).

Micah J. Cowan
Programmer, musician, typesetting enthusiast, gamer...
vox-tech mailing list

LUGOD Group on LinkedIn
Sign up for LUGOD event announcements
Your email address:
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:
EDGE Tech Corp.
For donating some give-aways for our meetings.