Board index » cppbuilder » unsigned char * to char *

unsigned char * to char *


2007-10-31 11:29:52 PM
cppbuilder99
In old C code I met the following
unsigned char *p1;
char *p2 = "abc";
...
p1 = p2;
Are any hidden dangers in this code?
Vladimir Grigoriev
 
 

Re:unsigned char * to char *

"Vladimir Grigoriev" < XXXX@XXXXX.COM >writes:
Quote
In old C code I met the following

unsigned char *p1;
char *p2 = "abc";

...

p1 = p2;

Are any hidden dangers in this code?
Yes.
1) p2 is a pointer to non-const data, initialized by a string literal
(an array of const characters). If you end up changing anything
through p2, it's undefined behavior. This initialization is
deprecated and only exists for backwards compatibility but should
not be used in new code.
2) the assignment should not compile since they're different types and
the pointed-to types do not have a visible inheritance
relationship.
--
Chris (TeamB);
 

Re:unsigned char * to char *

Quote
p1 = p2;

Are any hidden dangers in this code?
No, but personally I would show intent with a cast.
p1 = reinterpret_cast <unsigned char*>(p2);
// or
p1 = (unsigned char*) p2;
The only time that signed and unsigned numerals (char is a numeral) have
problems working together is during arithmetic. In C/C++ there is no
conversion performed when this cast is made.
Clayton
 

{smallsort}

Re:unsigned char * to char *

Quote
>Are any hidden dangers in this code?

Yes.

1) p2 is a pointer to non-const data, initialized by a string literal
[snip]
To explain further this following code would have the same hidden danger:
char *p1;
char *p2 = "abc";
p1 = p2;
... as well as the simple form ...
char *p1 = "abc";
*p1 = '\0'; // example of bad behavior
The constness is the danger (which I forgot to think about in my post). The
signedness is not.
Quote
2) the assignment should not compile since they're different types and
the pointed-to types do not have a visible inheritance
relationship.
One would think that but BCB and RAD both don't take issue.
Clayton
 

Re:unsigned char * to char *

"Clayton Arends" < XXXX@XXXXX.COM >writes:
Quote
>>Are any hidden dangers in this code?
>
>Yes.
>
>1) p2 is a pointer to non-const data, initialized by a string literal
>[snip]

To explain further this following code would have the same hidden danger:

char *p1;
char *p2 = "abc";

p1 = p2;
Just to clairify... assigning p2 to p1 is "safe", since it only
changes p2, but not the memory to which it points.
Quote
... as well as the simple form ...

char *p1 = "abc";
*p1 = '\0'; // example of bad behavior

The constness is the danger (which I forgot to think about in my
post). The signedness is not.
The only danger is when we dereference p1 and then write to that
memory, as shown in the cod emarked "...bad behavior"
Quote
>2) the assignment should not compile since they're different types and
>the pointed-to types do not have a visible inheritance
>relationship.

One would think that but BCB and RAD both don't take issue.
Seriously? It's a compiler bug then. Even if BCB implements char as
having a sign, "char" and "signed char" ar two distinct types. (In
fact, "char", "signed char", and "unsigned char" are *three* distinct
types, though obviously char will either be signed or unsigned in its
implementation, its TYPE is still different at the language level.
Oddly enough, is not true for int, unsigned int, and signed int, since
"int" is always just the shorthand way for writing signed int.)
--
Chris (TeamB);
 

Re:unsigned char * to char *

Chris Uzdavinis (TeamB) < XXXX@XXXXX.COM >writes:
Quote
>char *p1;
>char *p2 = "abc";
>
>p1 = p2;

Just to clairify... assigning p2 to p1 is "safe", since it only
changes p2, but not the memory to which it points.
Make that, "... it only changes p1, ..."
--
Chris (TeamB);
 

Re:unsigned char * to char *

Quote
One would think that but BCB and RAD both don't take issue.
Not quite true:
[BCC32 Warning] W8079 Mixing pointers to different 'char' types
 

Re:unsigned char * to char *

"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
Seriously? It's a compiler bug then. Even if BCB implements char as
having a sign, "char" and "signed char" ar two distinct types. (In
fact, "char", "signed char", and "unsigned char" are *three* distinct
types, though obviously char will either be signed or unsigned in its
implementation, its TYPE is still different at the language level.
Oddly enough, is not true for int, unsigned int, and signed int, since
"int" is always just the shorthand way for writing signed int.)
Chris (TeamB);
Are "char", "unsigned char", and "signed char" indeed three different types
in C and C++?
So if I have
signed char uc;
char c;
I must get a warning for the statement in any case either for C or for C++?
c = uc;
Vladimir Grigoriev
 

Re:unsigned char * to char *

Quote
[BCC32 Warning] W8079 Mixing pointers to different 'char' types
You must have that warning enabled by default (or have all warnings enabled
by default). Creating a new application in my system (using BCB6 and
RAD2007) doesn't generate this warning. After enabling all warnings for the
project then I get the warning.
Clayton
 

Re:unsigned char * to char *

Clayton Arends wrote:
Quote
BCB6 and RAD2007) doesn't generate this warning. After enabling all
warnings for the project then I get the warning.
Isn't that the first thing you do when creating new projects? ;)
 

Re:unsigned char * to char *

Quote
Isn't that the first thing you do when creating new projects? ;)
:D
 

Re:unsigned char * to char *

"Vladimir Grigoriev" < XXXX@XXXXX.COM >wrote:
Quote
Are "char", "unsigned char", and "signed char" indeed three different types
in C and C++?
Yes. IIRC, char will have the same representation as one of the other
two, but it is a separate type. Most especially, a pointer to one type
cannot be implicitly converted to a pointer of either other type.
Quote
So if I have

signed char uc;
char c;

I must get a warning for the statement in any case either for C or for C++?

c = uc;
Perhaps, perhaps not. If the char and the signed char type have exactly
the same range, then there is no reason for a warning. On the other
hand, if char is unsigned, then there are valid values for uc which
cannot be stored in c, and vice versa, and a warning is then
appropriate.
Alan Bellingham
--
Team Browns
<url:www.borland.com/newsgroups/>Borland newsgroup descriptions
<url:www.borland.com/newsgroups/netiquette.html>netiquette
 

Re:unsigned char * to char *

"Vladimir Grigoriev" < XXXX@XXXXX.COM >writes:
Quote
Are "char", "unsigned char", and "signed char" indeed three different types
in C and C++?
Yes.
Quote
So if I have

signed char uc;
char c;

I must get a warning for the statement in any case either for C or for C++?
This does not require a diagnostic, and warnings are not (ever)
required by the standard. The standard makes no differentiation
between errors and warnings, only specifying certain conditions that
require a "diagnostic message". Either a warning or an error
satisfies this requirement, but compilers are allowed to emit
additional messages if they thing they're helpful. (Which are what
most warnings are.)
--
Chris (TeamB);
 

Re:unsigned char * to char *

Vladimir Grigoriev < XXXX@XXXXX.COM >wrote:
Quote
"Chris Uzdavinis (TeamB)" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...
>Seriously? It's a compiler bug then. Even if BCB implements char as
>having a sign, "char" and "signed char" ar two distinct types. (In
>fact, "char", "signed char", and "unsigned char" are *three* distinct
>types, though obviously char will either be signed or unsigned in its
>implementation, its TYPE is still different at the language level.
>Oddly enough, is not true for int, unsigned int, and signed int, since
>"int" is always just the shorthand way for writing signed int.)
>Chris (TeamB);

Are "char", "unsigned char", and "signed char" indeed three different types
in C and C++?
3.9.1 Fundamental types
[...] It is implementation-defined whether a char object can hold
negative values. Characters can be explicitly declared unsigned
or signed. Plain char, signed char, and unsigned char are three
distinct types. [...]
Quote
[...]
Vladimir Grigoriev
Schobi
--
XXXX@XXXXX.COM is never read
I'm HSchober at gmx dot de
"A patched buffer overflow doesn't mean that there's one less way attackers
can get into your system; it means that your design process was so lousy
that it permitted buffer overflows, and there are probably thousands more
lurking in your code."
Bruce Schneier