473,325 Members | 2,805 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,325 software developers and data experts.

Warning when comparing char[] to a #define'd string

Hi,

let's say I have this:

#include <string.h>

#define BLAH "foo"

Later on, I do this:

unsigned char yadda [10];

/* ... get a couple of bytes ( = string) from buffer ... */

if (strcmp (BLAH, yadda) == 0) { printf ("yeehaw!\n"); }

This gives me the following warning:
warning: pointer targets in passing argument 1 of 'strcmp' differ in
signedness
I'm asking because I do not know about signed or unsigned in _quoted_
#define's.
Also several attempts of casting the stuff (both arg#1 + arg#2) failed.
Seems to be a gcc 4-only default to check this.
(I bet this was there in gcc3 also, it was just not enabled by default)

Thanks,
Andreas

Nov 7 '08 #1
13 2688
Andreas Eibach wrote:
let's say I have this:

#include <string.h>

#define BLAH "foo"

Later on, I do this:

unsigned char yadda [10];

/* ... get a couple of bytes ( = string) from buffer ... */

if (strcmp (BLAH, yadda) == 0) { printf ("yeehaw!\n"); }
This is no different from:

#include <string.h>

unsigned char yadda [10];

/* ... get a couple of bytes ( = string) from buffer ... */

if (strcmp ("foo", yadda) == 0) { printf ("yeehaw!\n"); }
This gives me the following warning:
warning: pointer targets in passing argument 1 of 'strcmp' differ in
signedness
You're comparing a (char *) and an (unsigned char *). The warning makes
sense. If yadda contains a string, it should be a char[], not an
unsigned char[].
I'm asking because I do not know about signed or unsigned in _quoted_
#define's.
The #define is irrelevant. See the simplification above.
Also several attempts of casting the stuff (both arg#1 + arg#2) failed.
Casting "foo" to (unsigned char *) or casting yadda to (char *) should
mask the warning, but the better solution is to use the correct types.
Seems to be a gcc 4-only default to check this.
(I bet this was there in gcc3 also, it was just not enabled by default)
Possibly; ask the GCC folks.

char might be unsigned on your system, but even so "char" and "unsigned
char" aren't exactly the same thing. It's not like "int" and "signed
int" being the same.

S
Nov 7 '08 #2

"Stephen Sprunk" <st*****@sprunk.orgwrote:
You're comparing a (char *) and an (unsigned char *). The warning makes
sense. If yadda contains a string, it should be a char[], not an
unsigned char[].
I'm asking because I do not know about signed or unsigned in _quoted_
#define's.

The #define is irrelevant. See the simplification above.
OK.
Also several attempts of casting the stuff (both arg#1 + arg#2) failed.

Casting "foo" to (unsigned char *) or casting yadda to (char *) should
mask the warning, but the better solution is to use the correct types.
Thanks for the tip - I did a few tests with modified code.
Three variations tested, two of them work, with one of the latter needing an
additional malloc().

Now it comes : :))

[variation #1+#2]

#include <string.h>

#define BLAH "foo"
char * yadda; /* variation #2: char yadda[10]; */

....malloc ()... /* for variation #2: do not use */

/* ... get a couple of bytes ( = string) from buffer ...*/

if (strcmp (BLAH, yadda) == 0) { printf ("yeehaw!\n"); }

both WORK!

BUT

[variation #3]
#include <string.h>

#define BLAH (unsigned char*) "foo"
....
unsigned char yadda[10]; /* unsigned char* ^= unsigned char[] */

/* ... get a couple of bytes ( = string) from buffer ... */
if (strcmp (BLAH, yadda) == 0) { printf ("yeehaw!\n"); }

gives me even TWO warnings!

So I will stick to using _signed_ char* in the strcmp(), even though I'm not
needing negative values.
Looks like strcmp() does not accept unsigned char*, even though both
arguments are now of same type.
Seems to be a gcc 4-only default to check this.
(I bet this was there in gcc3 also, it was just not enabled by default)

Possibly; ask the GCC folks.
Could be a good idea.
Thanks for the reply,

-Andreas

Nov 7 '08 #3
Stephen Sprunk wrote, On 07/11/08 17:52:
Andreas Eibach wrote:
>let's say I have this:

#include <string.h>

#define BLAH "foo"

Later on, I do this:

unsigned char yadda [10];

/* ... get a couple of bytes ( = string) from buffer ... */

if (strcmp (BLAH, yadda) == 0) { printf ("yeehaw!\n"); }
<snip>
>This gives me the following warning:
warning: pointer targets in passing argument 1 of 'strcmp' differ in
signedness

You're comparing a (char *) and an (unsigned char *). The warning makes
sense. If yadda contains a string, it should be a char[], not an
unsigned char[].
No he isn't, he is passing both to a function that expects to pointers
to char (not unsigned or signed but plain) which happens to do a comparison.
>I'm asking because I do not know about signed or unsigned in _quoted_
#define's.

The #define is irrelevant. See the simplification above.
>Also several attempts of casting the stuff (both arg#1 + arg#2) failed.

Casting "foo" to (unsigned char *) or casting yadda to (char *) should
mask the warning, but the better solution is to use the correct types.
Casting the string literal will just make matters worse because then it
will be two pointers which don't match in signedness instead of just one.
>Seems to be a gcc 4-only default to check this.
(I bet this was there in gcc3 also, it was just not enabled by default)

Possibly; ask the GCC folks.
It isn't enabled by default on my machine with gcc 4.3.2. It is enabled
if I specify -ansi -pedantic, which is correct as a diagnostic is required.
char might be unsigned on your system, but even so "char" and "unsigned
char" aren't exactly the same thing. It's not like "int" and "signed
int" being the same.
Casting yadda to char* removes the warning on my machine, but I would
seriously consider whether it should be plain char.
--
Flash Gordon
If spamming me sent it to sm**@spam.causeway.com
If emailing me use my reply-to address
See the comp.lang.c Wiki hosted by me at http://clc-wiki.net/
Nov 7 '08 #4
Andreas Eibach wrote, On 07/11/08 19:10:
"Stephen Sprunk" <st*****@sprunk.orgwrote:
<snip>
/* ... get a couple of bytes ( = string) from buffer ... */
if (strcmp (BLAH, yadda) == 0) { printf ("yeehaw!\n"); }

gives me even TWO warnings!
See my other reply.
So I will stick to using _signed_ char* in the strcmp(), even though I'm not
needing negative values.
Plain char is NOT signed char. On some systems it happens to be signed,
on some it is unsigned, but it is ALWAYS a distinct type from both.

Always use plain char for character data *unless* there is a specific
good reason to use something else.
Looks like strcmp() does not accept unsigned char*, even though both
arguments are now of same type.
<snip>

See my other reply.
--
Flash Gordon
If spamming me sent it to sm**@spam.causeway.com
If emailing me use my reply-to address
See the comp.lang.c Wiki hosted by me at http://clc-wiki.net/
Nov 7 '08 #5
Andreas Eibach wrote:
Hi,

let's say I have this:

#include <string.h>

#define BLAH "foo"

Later on, I do this:

unsigned char yadda [10];

/* ... get a couple of bytes ( = string) from buffer ... */

if (strcmp (BLAH, yadda) == 0) { printf ("yeehaw!\n"); }

This gives me the following warning:
warning: pointer targets in passing argument 1 of 'strcmp' differ in
signedness
Are you sure the error message matches the code you have shown?
If so, report the bug[*] to your compiler vendor. (Or upgrade to a
newer version. For what it's worth, your code elicits a warning from
gcc 4.3.2, but with that version the warning is correct.)
[*] Technically speaking it isn't a bug, because a compiler is
allowed to issue any diagnostic messages it cares to, even if those
messages are incorrect. Nonetheless, I think the maintainers of
the compiler in question would consider this behavior a bug, and
would thank you for reporting it.

--
Er*********@sun.com
Nov 7 '08 #6
Andreas Eibach wrote:
>
.... snip ...
>
So I will stick to using _signed_ char* in the strcmp(), even
though I'm not needing negative values. Looks like strcmp()
does not accept unsigned char*, even though both arguments are
now of same type.
No. You should recognize that there are three distinct types of
chars in C. char, signed char, and unsigned char. They are
distinct. For any implemented C system char has been set to be one
of signed char, or unsigned char. You don't necessarily know
which. What you do know is that strings are represented by arrays
of char (with a '\0' terminator), and are passed as pointers to
char (char*).

It looks as if your system has char set to be signed char. Don't
assume this in general.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Nov 8 '08 #7
Andreas Eibach wrote:
"Stephen Sprunk" <st*****@sprunk.orgwrote:
>>Also several attempts of casting the stuff (both arg#1 + arg#2) failed.

Casting "foo" to (unsigned char *) or casting yadda to (char *) should
mask the warning, but the better solution is to use the correct types.

Thanks for the tip - I did a few tests with modified code.
Three variations tested, two of them work, with one of the latter needing an
additional malloc().

Now it comes : :))

[variation #1+#2]

#include <string.h>

#define BLAH "foo"
char * yadda; /* variation #2: char yadda[10]; */

...malloc ()... /* for variation #2: do not use */

/* ... get a couple of bytes ( = string) from buffer ...*/

if (strcmp (BLAH, yadda) == 0) { printf ("yeehaw!\n"); }

both WORK!
They work because they're correct.
BUT

[variation #3]
#include <string.h>

#define BLAH (unsigned char*) "foo"
...
unsigned char yadda[10]; /* unsigned char* ^= unsigned char[] */

/* ... get a couple of bytes ( = string) from buffer ... */
if (strcmp (BLAH, yadda) == 0) { printf ("yeehaw!\n"); }

gives me even TWO warnings!
What warnings? I presume you mean the original warning about comparing
strings with different signed-ness is gone and there are two new ones
about passing (unsigned char *)s to a function expecting (char *)s?

If I saw this code, I'd warn you, too. (unsigned char *) is not the
right type to be using with strings. It'll probably work, but it
misleads the reader as to what's going on.
So I will stick to using _signed_ char* in the strcmp(), even though I'm not
needing negative values.
No, do not use (signed char *). When working with strings, always use
(char *). Even if (char) happens to be signed on your system, it is
still a distinct type from (signed char).
Looks like strcmp() does not accept unsigned char*, even though both
arguments are now of same type.
strcmp() is specified to take two arguments of type (char *). If you
pass in (signed char *) _or_ (unsigned char *), it's not surprising that
your compiler warns you about using the wrong type. When working with
strings, always use (char *).

S
Nov 8 '08 #8

"Flash Gordon" <sm**@spam.causeway.comschrieb:
Casting "foo" to (unsigned char *) or casting yadda to (char *) should
mask the warning, but the better solution is to use the correct types.

Casting the string literal will just make matters worse because then it
will be two pointers which don't match in signedness instead of just one.
True. I was just trying to keep it short :) but I also did try this 4th
variation.
And of course, I got 2 warnings about non-respected signedness.
char might be unsigned on your system, but even so "char" and "unsigned
char" aren't exactly the same thing. It's not like "int" and "signed
int" being the same.

Yes, I agree I had confused and set this equal to (un)signed int.
So there are three of the char* sort. I think now I won't forget about that
anymore. You definitely never stop learning. o_o

-Andreas

Nov 8 '08 #9

"Eric Sosman" <Er*********@sun.comwrote:
Are you sure the error message matches the code you have shown?
If so, report the bug[*] to your compiler vendor. (Or upgrade to a
newer version. For what it's worth, your code elicits a warning from
gcc 4.3.2,
Bingo. I was getting this with 4.3.2 indeed.
but with that version the warning is correct.)
Yup. Note that my post definitely was _not_ a complaint of that "gcc guys,
please fix your software" sort, but simply a presumption that I might have
forgotten about something. :) However, I could not sense that there are
three distinct char * types, unlike the int types which are either unsigned
or signed---thus two---and that's about it.

-Andreas

Nov 8 '08 #10

"Stephen Sprunk" <st*****@sprunk.orgschrieb:
When working with strings, always use (char *).
Promised henceforth. :)
Since I know there are 3 distinct subtypes, which blatantly escaped me. Doh.

-Andreas

Nov 8 '08 #11
CBFalconer <cb********@yahoo.comwrites:
Andreas Eibach wrote:
>>
... snip ...
>>
So I will stick to using _signed_ char* in the strcmp(), even
though I'm not needing negative values. Looks like strcmp()
does not accept unsigned char*, even though both arguments are
now of same type.

No. You should recognize that there are three distinct types of
chars in C. char, signed char, and unsigned char. They are
distinct.
Right.
For any implemented C system char has been set to be one
of signed char, or unsigned char. You don't necessarily know
which.
And here you contradict your earlier statement. I know what you
meant, but it's not quite what you said. For any C implementation,
type char isn't "set to be" either signed char or unsigned char; it's
set to have the same characteristics (size, range, representation) as
either signed char or unsigned char. It's still a distinct type, as
you correctly stated above.

For example:

char *pc = NULL;
unsigned char *puc;
signed char *psc;
puc = pc; /* constraint violation */
psc = pc; /* constraint violation */

*Both* marked lines are constraint violations, regardless of the
signedness of plain char.
What you do know is that strings are represented by arrays
of char (with a '\0' terminator), and are passed as pointers to
char (char*).
String literals certainly are. I think that the standard's definition
of "string", as "a contiguous sequence of characters terminated by and
including the first null character", allows an array of unsigned char
to contain a "string"; a "character" can be either a char, a signed
char, or an unsigned char.
It looks as if your system has char set to be signed char. Don't
assume this in general.
You mean "set to have the same representation as".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 8 '08 #12
Andreas Eibach wrote:
"Eric Sosman" <Er*********@sun.comwrote:
> Are you sure the error message matches the code you have shown?
If so, report the bug[*] to your compiler vendor. (Or upgrade to a
newer version. For what it's worth, your code elicits a warning from
gcc 4.3.2,

Bingo. I was getting this with 4.3.2 indeed.
Apparently I was being too subtle. Let me try again:
"Andreas, you are lying. The code you showed did *not*
elicit the warning you showed, and you are guilty of
mis-reporting. The `this' you mention was in fact
`something else'."

I'm pretty sure I know what mistake you made, and I
know what message you actually got (or, if you actually
got that message, what your code actually looked like).
The point of the scolding is simply this: When you report
that "Code X gave me message Y," do not replace X and Y
by W and Q! It's bad for the diagnosis.

"Doctor, I have this terrible pain in my left ankle."
"I see nothing wrong with your left ankle." "Oh, what I
really meant was my right hip ... maybe. Guess again."

--
Eric Sosman
es*****@ieee-dot-org.invalid
Nov 8 '08 #13

"Eric Sosman" <es*****@ieee-dot-org.invalidschrieb:
Apparently I was being too subtle. Let me try again:
"Andreas, you are lying. The code you showed did *not*
elicit the warning you showed, and you are guilty of
mis-reporting. The `this' you mention was in fact
`something else'."
Yes, Your Honor. :P

-Andreas
Nov 8 '08 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Eric Lilja | last post by:
Hello, I have a few global variables in my program. One of them holds the name of the application and it's defined in a header file globals.hpp (and the point of definition also happen to be the...
27
by: ruel loehr | last post by:
Hey guys, I am looking for some insight: Given two sorted arrays of integers A and B, where array B has enough extra room in it to hold the contents of both A and B. Merge array A and B...
43
by: Anitha | last post by:
Hi I observed something while coding the other day: if I declare a character array as char s, and try to use it as any other character array..it works perfectly fine most of the times. It...
3
by: Bas Wassink | last post by:
Hello there, I'm having trouble understanding a warning produced by 'splint', a code-checker. The warning produced is: keywords.c: (in function keyw_get_string) keywords.c:60:31: Released...
18
by: JohnR | last post by:
From reading the documentation, this should be a relatively easy thing. I have an arraylist of custom class instances which I want to search with an"indexof" where I'm passing an instance if the...
5
by: Roman Mashak | last post by:
Hello, All! I already posted my question and received valuable feedbacks, I changed my code as was proposed here but still receive the same error of valgrind. SO, the code is: #define...
2
by: dasilva109 | last post by:
Hi guys I am new to C++ and need urgent help with this part of my code for a uni coursework I have to submit by Thursday //ClientData.h #ifndef CLIENTDATA_H #define CLIENTDATA_H #include...
5
by: J.Broeden | last post by:
Hi, I've written a some code to assist in my understanding of strings using some of Cs built in character handling functions but I am not sure why I'm getting the following error. I hope someone...
22
by: mdh | last post by:
Hi All, Happy Solstice! May I ask the following. The following is a brief excerpt of a practice program. main(...){ if (argc 1 && mystrcomp(argv, "-n") == 0) /* argv is "-n" / ******/...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.