Type Mismatch: Signed to Unsigned - c++

I have the following line of code,
const CHAR* GetText() { return Text; } // Text is char[16]"Character Array"
The Fortify security tool is complaining about the above line as follows:
Type Mismatch: Signed to Unsigned GetText()is declared to return an unsigned value, but on line xxx it returns a signed value.
I did not understand where i am converting it from signed to unsigned. I do understand the signed to unsigned conversion stuff if it is related to integers.
If i inferred correctly from the line of code,
Is char which being returned a signed char?
Is LPCSTR(const char*)the return type is unsigned char?
How do we assume (Text-which is a string) is signed and unsigned?
Any help would be appreciated.

Related

How to initialize a signed char to unsigned values like 0xFF in C++?

There are some cases where a byte array is implemented in a library using a char type, which is a signed type for many compilers.
Is there a simple, readable and correct way to initialize a signed char with a hex value which is greater than 127 and not bigger than 255?
Currently I end up with the following, and I keep thinking that there must be something simpler:
const unsigned char ff_unsigned = 0xff;
const char ff_signed = static_cast<const char>(ff_unsigned);
I want a solution with no warnings, even when using higher compiler warning levels than the default.
The following solution e.g. creates C4310: cast truncates constant value with MSVC 2013:
const char ff_signed = char(0xff);
Yes there is. Use single quotation characters with \x as the prefix. That denotes a hexadecimal literal char type.
For example: '\xff'.
But note that char can be signed or unsigned and up to and including C++11 it can even be a 1's complement signed type.
const char ff_unsigned = '\xff';
0xff is an int and '\xff' is a char.`You can use
const char ff_signed = (char)0xff;
or
const char ff_signed = '\xff';

How to convert unsigned int (pointer) to const char in C++

How do I convert an unsigned int (UINT32) to a const char.
I tried to cast it but because isn’t type safe is crashing when the pointer is bigger than expected.
So how can I approach this correctly?
unsigned int p = 0x32422342;
strLocation = QString::fromUtf8((char*)p, sizeof(p));
BTW if I leave the cast, the compiler is showing up an exception:
cast to `const char*`from smaller integer type `UINT32` (aka `unsigned int`) [-Wint-to-pointer-cast]
any suggestions? The value is just a random number, just for clarification.
Your pointers are probably 64 bits long, this is why your compiler complains... Are you sure that your 32 bits represents a good address ? Probably not.

Converting element in char array to int

I have an 80 element char array and I am trying to specific elements to an integer and am getting some number errors.
Array element 40 in hex is 0xC0. When I try assigning it to an integer I get in hex 0xFFFFC0, and I dont know why.
char tempArray[80]; //Read in from file, with element 40 as 0xC0
int tempInt = (int)tempArray[40]; //Output as 0xFFFFC0 instead of 0x0000C0
Depending on your implementation, a char type in C++ is either a signed type or an unsigned type. (The C++ standard mandates that an implementation chooses either scheme).
To be on the safe side, use unsigned char in your case.
This is so because char is treated as signed number, and the promotion to int preserves the sign. Change the array from char to unsigned char to avoid it.
Because 0XC0 is negative in char, and the cast is preserving the sign as an int. You should use unsigned char if you want to maintain the directly binary translation or as a purely positive value
for more convenience, I always use unsigned and signed always before declaration and casting. you can write the following:
unsigned char tempArray[80]; //Read in from file, with element 40 as 0xC0
unsigned int tempInt = (unsigned int)tempArray[40]; //Output as 0xFFFFC0 instead of 0x0000C0
char may be signed, so converting from a negative char value will result in a negative int value, which is usualyl represented in two's complement, resulting in a very high binary representation.
Instead, either use int tempInt = 0xFF & tempArray[40], define tempArray as unsigned char, or cast to unsigned char : int tempInt = (unsigned char)tempArray[40] (unsure if this is defined behaviour).

error: overflow in implicit constant conversion [-Werror=overflow]

error: overflow in implicit constant conversion [-Werror=overflow]
#include<stdio.h>
int main()
{
char ch=200;
printf("\n%d",ch);
return 0;
}
I am running this code on http://ideone.com/YNkKT6#view_edit_box and getting the implicit conversion error.
What modification do I need and what is the reason?
n3376 3.9.1/1
Plain char, signed char, and unsigned char are three distinct types. A char, a signed char, and an
unsigned char occupy the same amount of storage and have the same alignment requirements (3.11); that is,
they have the same object representation.
What is char is implementation-defined, so, you need unsigned char here, that handles values (0-255).
looks like your char is signed char, which accept value from -128 to 127. and 200 is too large for it and will overflow to be a negative number.
to fix it, change char to int or unsigned char
int main()
{
unsigned char ch=200;
printf("\n%d",ch);
return 0;
}

Conversion from unsigned to signed type safety?

Is it safe to convert, say, from an unsigned char * to a signed char * (or just a char *?
The access is well-defined, you are allowed to access an object through a pointer to signed or unsigned type corresponding to the dynamic type of the object (3.10/15).
Additionally, signed char is guaranteed not to have any trap values and as such you can safely read through the signed char pointer no matter what the value of the original unsigned char object was.
You can, of course, expect that the values you read through one pointer will be different from the values you read through the other one.
Edit: regarding sellibitze's comment, this is what 3.9.1/1 says.
A char, a signed char, and an unsigned char occupy the same amount of storage and have the same alignment requirements (3.9); that is, they have the same object representation. For character types, all bits of the object representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers.
So indeed it seems that signed char may have trap values. Nice catch!
The conversion should be safe, as all you're doing is converting from one type of character to another, which should have the same size. Just be aware of what sort of data your code is expecting when you dereference the pointer, as the numeric ranges of the two data types are different. (i.e. if your number pointed by the pointer was originally positive as unsigned, it might become a negative number once the pointer is converted to a signed char* and you dereference it.)
Casting changes the type, but does not affect the bit representation. Casting from unsigned char to signed char does not change the value at all, but it affects the meaning of the value.
Here is an example:
#include <stdio.h>
int main(int args, char** argv) {
/* example 1 */
unsigned char a_unsigned_char = 192;
signed char b_signed_char = b_unsigned_char;
printf("%d, %d\n", a_signed_char, a_unsigned_char); //192, -64
/* example 2 */
unsigned char b_unsigned_char = 32;
signed char a_signed_char = a_unsigned_char;
printf("%d, %d\n", b_signed_char, b_unsigned_char); //32, 32
return 0;
}
In the first example, you have an unsigned char with value 192, or 110000000 in binary. After the cast to signed char, the value is still 110000000, but that happens to be the 2s-complement representation of -64. Signed values are stored in 2s-complement representation.
In the second example, our unsigned initial value (32) is less than 128, so it seems unaffected by the cast. The binary representation is 00100000, which is still 32 in 2s-complement representation.
To "safely" cast from unsigned char to signed char, ensure the value is less than 128.
It depends on how you are going to use the pointer. You are just converting the pointer type.
You can safely convert an unsigned char* to a char * as the function you are calling will be expecting the behavior from a char pointer, but, if your char value goes over 127 then you will get a result that will not be what you expected, so just make certain that what you have in your unsigned array is valid for a signed array.
I've seen it go wrong in a few ways, converting to a signed char from an unsigned char.
One, if you're using it as an index to an array, that index could go negative.
Secondly, if inputted to a switch statement, it may result in a negative input which often is something the switch isn't expecting.
Third, it has different behavior on an arithmetic right shift
int x = ...;
char c = 128
unsigned char u = 128
c >> x;
has a different result than
u >> x;
Because the former is sign-extended and the latter isn't.
Fourth, a signed character causes underflow at a different point than an unsigned character.
So a common overflow check,
(c + x > c)
could return a different result than
(u + x > u)
Safe if you are dealing with only ASCII data.
I'm astonished it hasn't been mentioned yet: Boost numeric cast should do the trick - but only for the data of course.
Pointers are always pointers. By casting them to a different type, you only change the way the compiler interprets the data pointed to.