469,904 Members | 2,288 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,904 developers. It's quick & easy.

gcc 4 signed vs unsigned char

Hello,
I've just switched to gcc 4 and I came across a bunch of warnings that
I can't fix. Example:

#include <stdio.h>

int main()
{
signed char *p = "Hola";

return 0;
}

If I compile that file, I get:
kk.c: In function 'main':
kk.c:5: warning: pointer targets in initialization differ in signedness

Only if I remove the signed from the declaration it compiles without
errors. How can I use the signed or unsigned char?

I'm using gcc 4.0.1. The reason for asking this is because in one
program I'm always using int8_t and u_int8_t values, and both of them
are signed or unsigned, no simply 'char' variables.

Thanks in advance.

Nov 15 '05 #1
22 5315


ju********@gmail.com wrote:
Hello,
I've just switched to gcc 4 and I came across a bunch of warnings that
I can't fix. Example:

#include <stdio.h>

int main()
{
signed char *p = "Hola";

return 0;
}

If I compile that file, I get:
kk.c: In function 'main':
kk.c:5: warning: pointer targets in initialization differ in signedness

Only if I remove the signed from the declaration it compiles without
errors. How can I use the signed or unsigned char?

I'm using gcc 4.0.1. The reason for asking this is because in one
program I'm always using int8_t and u_int8_t values, and both of them
are signed or unsigned, no simply 'char' variables.

Thanks in advance.


in gcc 3.4. it's ok!

Nov 15 '05 #2
ju********@gmail.com wrote:
Hello,
I've just switched to gcc 4 and I came across a bunch of warnings that
I can't fix. Example:

#include <stdio.h>

int main()
{
signed char *p = "Hola";

return 0;
}

If I compile that file, I get:
kk.c: In function 'main':
kk.c:5: warning: pointer targets in initialization differ in signedness

Only if I remove the signed from the declaration it compiles without
errors. How can I use the signed or unsigned char?

I'm using gcc 4.0.1. The reason for asking this is because in one
program I'm always using int8_t and u_int8_t values, and both of them
are signed or unsigned, no simply 'char' variables.


The type char is - for historical reasons - distinct from signed char
and unsigned char and may be effectively (signedness, size, range)
either the one or the other.
So, only
char *p = "Hola";
is always correct.
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 15 '05 #3
ju********@gmail.com writes:
I've just switched to gcc 4 and I came across a bunch of warnings that
I can't fix. Example:

#include <stdio.h>

int main()
{
signed char *p = "Hola";

return 0;
}

If I compile that file, I get:
kk.c: In function 'main':
kk.c:5: warning: pointer targets in initialization differ in signedness

Only if I remove the signed from the declaration it compiles without
errors. How can I use the signed or unsigned char?

I'm using gcc 4.0.1. The reason for asking this is because in one
program I'm always using int8_t and u_int8_t values, and both of them
are signed or unsigned, no simply 'char' variables.


Why would you want to use either signed char or int8_t for a character
string? The correct declaration is

char *p = "Hola";

"Plain" char is a distinct type from both signed char and unsigned
char, though it has the same representation as one of them.

However, the warning is misleading. The initialization is illegal (a
constraint violation), but the pointer targets don't actually differ
in signedness. I've just submitted a bug report; see
<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23087>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #4
Me
ju********@gmail.com wrote:
Hello,
I've just switched to gcc 4 and I came across a bunch of warnings that
I can't fix. Example:

#include <stdio.h>

int main()
{
signed char *p = "Hola";

return 0;
}

If I compile that file, I get:
kk.c: In function 'main':
kk.c:5: warning: pointer targets in initialization differ in signedness

Only if I remove the signed from the declaration it compiles without
errors.
"Hola" is a const char[5] which can be implicitly converted to const
char * and also unfortunately to just char *. What makes you think it
can also be implicitly converted to signed char *?

It's best to just think of unsigned char as the native byte type,
signed char as the corresponding signed integer, and plain char as a
separate native character type that just happens to be required to be
represented by either an unsigned char or signed char. It's unfortunate
it is this way but it's very, very unlikey to change.
How can I use the signed or unsigned char?
static signed char hola[] = "Hola";
signed char *p = hola;

Maybe you're confused why this works but your example doesn't. It's
because this is just syntax sugar for:

static signed char hola[5] = { 'H', 'o', 'l', 'a', '\0' };
signed char *p = hola;

(you can also get rid of the static and/or add a const qualifier. I
don't know how your actual code looks like from this small snippet)
I'm using gcc 4.0.1. The reason for asking this is because in one
program I'm always using int8_t and u_int8_t values, and both of them
are signed or unsigned, no simply 'char' variables.


who said int8_t and uint8_t must be typedeffed to a character type in
the first place? Consider it a good thing you get this warning (it
would be better if it was an error instead).

Nov 15 '05 #5


Me wrote:
ju********@gmail.com wrote:
Hello,
I've just switched to gcc 4 and I came across a bunch of warnings that
I can't fix. Example:

#include <stdio.h>

int main()
{
signed char *p = "Hola";

return 0;
}

If I compile that file, I get:
kk.c: In function 'main':
kk.c:5: warning: pointer targets in initialization differ in signedness

Only if I remove the signed from the declaration it compiles without
errors.

"Hola" is a const char[5] which can be implicitly converted to const
char * and also unfortunately to just char *.


Almost, but not quite. "Hola" is a char[5] that decays
to char* in most circumstances. Neither the array nor the
pointer is const-qualified, even though it is forbidden to
try to modify the array.

--
Er*********@sun.com

Nov 15 '05 #6
ju********@gmail.com wrote:
Hello,
I've just switched to gcc 4 and I came across a bunch of warnings that
I can't fix. Example:

#include <stdio.h>

int main()
{
signed char *p = "Hola";

return 0;
}

If I compile that file, I get:
kk.c: In function 'main':
kk.c:5: warning: pointer targets in initialization differ in signedness

Only if I remove the signed from the declaration it compiles without
errors. How can I use the signed or unsigned char?
You should write code that works just as well whether plain char
is signed or not.
I'm using gcc 4.0.1. The reason for asking this is because in one
program I'm always using int8_t and u_int8_t values, and both of them
are signed or unsigned, no simply 'char' variables.


You could avoid the warning with:
signed char *p = (signed char *)"Hola";

However I can't think of a reason why you would prefer this
to:
char const *p = "Hola";

Can you post some code that demonstrates why you need to
point to non-const, signed chars?

Nov 15 '05 #7
Eric Sosman <er*********@sun.com> writes:
Me wrote:

[...]
"Hola" is a const char[5] which can be implicitly converted to const
char * and also unfortunately to just char *.


Almost, but not quite. "Hola" is a char[5] that decays
to char* in most circumstances. Neither the array nor the
pointer is const-qualified, even though it is forbidden to
try to modify the array.


"Forbidden" in the sense that attempting to do so invokes undefined
behavior. For some implementations, this is indistinguishable from it
being allowed.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #8
Keith Thompson wrote:
ju********@gmail.com writes:

int main()
{
signed char *p = "Hola";
return 0;
}

If I compile that file, I get:
kk.c: In function 'main':
kk.c:5: warning: pointer targets in initialization differ in signedness


However, the warning is misleading. The initialization is illegal (a
constraint violation), but the pointer targets don't actually differ
in signedness. I've just submitted a bug report...


I, for one, am happy with the warning issued: "definitely signed"
is different to "maybe signed".

Plus the OP didn't indicate whether his implementation has plain
char signed or not, and if plain char were unsigned, then the
warning is definitely correct. GCC has a switch for that, and I
also think it defaults to unsigned on appropriate platforms
(eg. ARM).

Nov 15 '05 #9
"Old Wolf" <ol*****@inspire.net.nz> writes:
Keith Thompson wrote:
ju********@gmail.com writes:
>
> int main()
> {
> signed char *p = "Hola";
> return 0;
> }
>
> If I compile that file, I get:
> kk.c: In function 'main':
> kk.c:5: warning: pointer targets in initialization differ in signedness
>
However, the warning is misleading. The initialization is illegal (a
constraint violation), but the pointer targets don't actually differ
in signedness. I've just submitted a bug report...


I, for one, am happy with the warning issued: "definitely signed"
is different to "maybe signed".


But "signed though it's not required to be" and "signed because it's
required to be" don't "differ in signedness". The message should say
that they differ in type.

If I saw that message and didn't know that plain char is signed, I
would naturally assume that the compiler is complaining because plain
char is unsigned. If I found that plain char really is unsigned, I'd
submit a bug report against the compiler. (In fact, I did!)
Plus the OP didn't indicate whether his implementation has plain
char signed or not, and if plain char were unsigned, then the
warning is definitely correct. GCC has a switch for that, and I
also think it defaults to unsigned on appropriate platforms
(eg. ARM).


The warning wouldn't be as incorrect if plain char were unsigned, but
it would still be misleading. The initialization is illegal because
the pointer types are incompatible (and the pointer types are
incompatible because the target types are distinct types), *not*
just because the target types differ in signedness.

gcc 4.0.0 produces the warning "pointer targets in initialization
differ in signedness" for both of the following lines:

signed char *ps = "signed?";
unsigned char *pu = "unsigned?";

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #10
Keith Thompson wrote:
Eric Sosman <er*********@sun.com> writes:
Me wrote:


[...]
"Hola" is a const char[5] which can be implicitly converted to const
char * and also unfortunately to just char *.


Almost, but not quite. "Hola" is a char[5] that decays
to char* in most circumstances. Neither the array nor the
pointer is const-qualified, even though it is forbidden to
try to modify the array.

"Forbidden" in the sense that attempting to do so invokes undefined
behavior. For some implementations, this is indistinguishable from it
being allowed.


True: "undefined" is undefined. My point is that there
is no const qualifier to warn one away from attempting the
unthinkable.

If one were re-designing C "from the ground up" today,
string literals would surely be const-qualified. They are
not, though. The Rationale says

[...] string literals do not have the type /array of
const char/ in order to avoid problems of pointer type
checking, particularly with library functions, since
assigning a /pointer to const char/ to a plain /pointer
to char/ is not valid.

That is, prior to C89 there was no way to say "const" in a C
program. Nowadays if you write a function taking a string
argument that the function does not modify, you use the type
"const char*" for the argument. But the huge body of pre-C89
code had to type such arguments as simply "char*" -- and if
C89 had changed the type of string literals to "const char"
it would have suddenly broken all that pre-existing code. As
the Rationale says elsewhere, "Existing code is important,
existing implementations are not." A brand-new Standard that
provoked compilation errors in practically every existing
perfectly good program might have met some resistance to wide
adoption ... It's as if the Standard had not only permitted
but required the use of function prototypes: no project manager
in his right mind would have chosen to adopt a Standard whose
only effect was to create expensive busy-work for his staff.

String literals are non-const for "hysterical raisins."
This is not the only C feature with such a rationale.

--
Eric Sosman
es*****@acm-dot-org.invalid
Nov 15 '05 #11
>That is, prior to C89 there was no way to say "const" in a C
program. Nowadays if you write a function taking a string
argument that the function does not modify, you use the type
"const char*" for the argument.


Except there's still a problem. Take a function which returns a
pointer *INTO* one of its arguments (or possibly NULL). Examples
in the C library include strchr(), strrchr(), and strstr(), but you
can imagine lots of parsing functions that do that. Now, if you
pass in a const-poisoned pointer, it needs to be const-poisoned in
the return type. If you pass in a non-const-poisoned pointer, it
needs to be not const-poisoned on the way out, so you can use it
to write on the string. I need two nearly-identical copies of every
type of this function, one const-poisoned, the other not? Yeech.
C isn't C++ with its overloading.

Regardless of any existing code, this is still a problem.

Gordon L. Burditt

Nov 15 '05 #12
Old Wolf ha escrito:
ju********@gmail.com wrote:
Hello,
I've just switched to gcc 4 and I came across a bunch of warnings that
I can't fix. Example:

#include <stdio.h>

int main()
{
signed char *p = "Hola";

return 0;
}

If I compile that file, I get:
kk.c: In function 'main':
kk.c:5: warning: pointer targets in initialization differ in signedness

Only if I remove the signed from the declaration it compiles without
errors. How can I use the signed or unsigned char?


You should write code that works just as well whether plain char
is signed or not.
I'm using gcc 4.0.1. The reason for asking this is because in one
program I'm always using int8_t and u_int8_t values, and both of them
are signed or unsigned, no simply 'char' variables.


You could avoid the warning with:
signed char *p = (signed char *)"Hola";

However I can't think of a reason why you would prefer this
to:
char const *p = "Hola";

Can you post some code that demonstrates why you need to
point to non-const, signed chars?


The reason is just that I'm using always int8_t instead of char, is
that correct and portable for all platforms? (int8_t is a signed char)

Nov 15 '05 #13
ju********@gmail.com writes:
Old Wolf ha escrito:
ju********@gmail.com wrote:
> Hello,
> I've just switched to gcc 4 and I came across a bunch of warnings that
> I can't fix. Example:
>
> #include <stdio.h>
>
> int main()
> {
> signed char *p = "Hola";
>
> return 0;
> }
>
> If I compile that file, I get:
> kk.c: In function 'main':
> kk.c:5: warning: pointer targets in initialization differ in signedness
>
> Only if I remove the signed from the declaration it compiles without
> errors. How can I use the signed or unsigned char?


You should write code that works just as well whether plain char
is signed or not.
> I'm using gcc 4.0.1. The reason for asking this is because in one
> program I'm always using int8_t and u_int8_t values, and both of them
> are signed or unsigned, no simply 'char' variables.


You could avoid the warning with:
signed char *p = (signed char *)"Hola";

However I can't think of a reason why you would prefer this
to:
char const *p = "Hola";

Can you post some code that demonstrates why you need to
point to non-const, signed chars?


The reason is just that I'm using always int8_t instead of char, is
that correct and portable for all platforms? (int8_t is a signed char)


Your problem is simple: you're using int8_t instead of char.

The solution is equally simple: use char.

Is there some reason you're using int8_t when char is more appropriate?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #14
On 2005-07-27 15:10:23 -0400, ju********@gmail.com said:
Old Wolf ha escrito:

You could avoid the warning with:
signed char *p = (signed char *)"Hola";

However I can't think of a reason why you would prefer this
to:
char const *p = "Hola";

Can you post some code that demonstrates why you need to
point to non-const, signed chars?


The reason is just that I'm using always int8_t instead of char, is
that correct and portable for all platforms? (int8_t is a signed char)


The question is: "Why?"
Why are you using int8_t?

--
Clark S. Cox, III
cl*******@gmail.com

Nov 15 '05 #15
ju********@gmail.com wrote:
Old Wolf ha escrito:

.... snip ...

Can you post some code that demonstrates why you need to
point to non-const, signed chars?


The reason is just that I'm using always int8_t instead of char,
is that correct and portable for all platforms? (int8_t is a
signed char)


No, it is not. int_8t need not even be available on all
platforms. char will be available.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 15 '05 #16
Keith Thompson wrote:

gcc 4.0.0 produces the warning "pointer targets in initialization
differ in signedness" for both of the following lines:

signed char *ps = "signed?";
unsigned char *pu = "unsigned?";


I don't pretend to speak for anyone else here, but for me that
error message is more informative and allows me to understand
the error more quickly than "pointer targets are incompatible"
would.

Nov 15 '05 #17
Keith Thompson ha escrito:
ju********@gmail.com writes:
Old Wolf ha escrito:
ju********@gmail.com wrote:
> Hello,
> I've just switched to gcc 4 and I came across a bunch of warnings that
> I can't fix. Example:
>
> #include <stdio.h>
>
> int main()
> {
> signed char *p = "Hola";
>
> return 0;
> }
>
> If I compile that file, I get:
> kk.c: In function 'main':
> kk.c:5: warning: pointer targets in initialization differ in signedness
>
> Only if I remove the signed from the declaration it compiles without
> errors. How can I use the signed or unsigned char?

You should write code that works just as well whether plain char
is signed or not.

> I'm using gcc 4.0.1. The reason for asking this is because in one
> program I'm always using int8_t and u_int8_t values, and both of them
> are signed or unsigned, no simply 'char' variables.

You could avoid the warning with:
signed char *p = (signed char *)"Hola";

However I can't think of a reason why you would prefer this
to:
char const *p = "Hola";

Can you post some code that demonstrates why you need to
point to non-const, signed chars?


The reason is just that I'm using always int8_t instead of char, is
that correct and portable for all platforms? (int8_t is a signed char)


Your problem is simple: you're using int8_t instead of char.

The solution is equally simple: use char.

Is there some reason you're using int8_t when char is more appropriate?


I've always thought that using int8_t would be more portable, but it
seems I was wrong. I'll change my code to use char then :) Thanks for
everything.

Nov 15 '05 #18
I thougth that using int8_t would be more portable. Anyway, in my code
I also use int8_t, int16_t, int32_t (and their unsigned versions)
instead of using int, short, long ... Should I use the intx_t or the
int, short, etc? My main aim is portability among platforms.

Nov 15 '05 #19
On 27 Jul 2005 23:44:52 -0700,
ju********@gmail.com <ju********@gmail.com> wrote:

I thougth that using int8_t would be more portable. Anyway, in my code
I also use int8_t, int16_t, int32_t (and their unsigned versions)
instead of using int, short, long ... Should I use the intx_t or the
int, short, etc? My main aim is portability among platforms.


It is! If it is important that the type is exactly 8 bits. If
the program is compiled on a system which doesn't support 8 bit integer
types the compile would fail, which is actualy better than it silently
fails during execution. If it is not important that the type being
exactly 8 bits, then use char.

Villy
Nov 15 '05 #20
ju********@gmail.com writes:
I thougth that using int8_t would be more portable. Anyway, in my code
I also use int8_t, int16_t, int32_t (and their unsigned versions)
instead of using int, short, long ... Should I use the intx_t or the
int, short, etc? My main aim is portability among platforms.


Use whatever type is appropriate to your task. If you need an 8-bit
2's-complement type with no padding bits, use int8_t (assuming you
have a C99 implementation) -- but chances are you don't really need
all those properties.

If you need a signed type that's at least 16 bits, use int_least16_t.
Or use int.

And if you need to represent characters, use char; that's what it's
for.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #21
On Wed, 27 Jul 2005 02:52:30 +0000, Gordon Burditt wrote:
That is, prior to C89 there was no way to say "const" in a C
program. Nowadays if you write a function taking a string
argument that the function does not modify, you use the type
"const char*" for the argument.


Except there's still a problem. Take a function which returns a
pointer *INTO* one of its arguments (or possibly NULL). Examples
in the C library include strchr(), strrchr(), and strstr(), but you
can imagine lots of parsing functions that do that. Now, if you
pass in a const-poisoned pointer, it needs to be const-poisoned in
the return type. If you pass in a non-const-poisoned pointer, it
needs to be not const-poisoned on the way out, so you can use it
to write on the string. I need two nearly-identical copies of every
type of this function, one const-poisoned, the other not? Yeech.
C isn't C++ with its overloading.


While you can't fix this for existing standard library functions short
of casting the return value when you need a pointer to const, you can
design your own functions to avoid this, e.g. by returning an offset
instead of a pointer. Doing this also avoids a possible need for taking
pointer differences and the range issues of ptrdiff_t.

Lawrence
Nov 15 '05 #22
>>>That is, prior to C89 there was no way to say "const" in a C
program. Nowadays if you write a function taking a string
argument that the function does not modify, you use the type
"const char*" for the argument.


Except there's still a problem. Take a function which returns a
pointer *INTO* one of its arguments (or possibly NULL). Examples
in the C library include strchr(), strrchr(), and strstr(), but you
can imagine lots of parsing functions that do that. Now, if you
pass in a const-poisoned pointer, it needs to be const-poisoned in
the return type. If you pass in a non-const-poisoned pointer, it
needs to be not const-poisoned on the way out, so you can use it
to write on the string. I need two nearly-identical copies of every
type of this function, one const-poisoned, the other not? Yeech.
C isn't C++ with its overloading.


While you can't fix this for existing standard library functions short
of casting the return value when you need a pointer to const, you can
design your own functions to avoid this, e.g. by returning an offset
instead of a pointer. Doing this also avoids a possible need for taking
pointer differences and the range issues of ptrdiff_t.


You also have to deal with the case where the function would return
NULL. I suppose you could use offset -1 for this case. (At least
ptrdiff_t is signed). It looks ugly. I guess it would work, though.

Gordon L. Burditt
Nov 15 '05 #23

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

19 posts views Thread by MiniDisc_2k2 | last post: by
3 posts views Thread by Siemel Naran | last post: by
19 posts views Thread by Christopher Benson-Manica | last post: by
9 posts views Thread by dam_fool_2003 | last post: by
8 posts views Thread by Marcin Kalicinski | last post: by
11 posts views Thread by Frederick Gotham | last post: by
6 posts views Thread by Kislay | last post: by
1 post views Thread by Waqarahmed | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.