What is the difference between signed and normal short - c++

What is the difference between signed and normal short in c++? Is the range is different?

short is signed by default, so there is no difference.

The names signed short int, signed short, short int and short are synonymes and mean same type in C++.

Integers are signed by default in C++, which IMO brings the existence of the signed keyword into question. Technically, it is redundant, maybe it does contribute with some clarity, but hardly anyone uses it in production. Everyone is pretty much aware integers are signed by default. I honestly can't remember the last time I've seen signed in production code.
As for floats and doubles - they cannot be unsigned at all, they are always signed.
In this regard C++ syntax is a little redundant, at least IMO. There is a number of different ways to say the same thing, e.g. signed short int, signed short, short int and short , and what you say still might be platform or even compiler dependent.
Frameworks like Qt for example declare their own conventions which are shorter and informative, like for example:
quint8, quint16, quint32, quint64 are all unsigned integers, with the number signifying the size in bits, in the same logic:
qint8, qint16, qint32, qint64 are signed integers with the respective bit width.
uint is, at least for me, much more preferable to either unsigned or unsigned int, in the same logic you also have ushort which is preferable to unsigned short int. There is also uchar to complete the short-hard family.

Related

Porting program, curious if int16_t & __int16 are 'the same'

So i am porting one of my programs to a new gaming console. The problem is that the SDK used to compile my c++ application doesn't support __int16, BUT it does have int16_t.
Would it be 'safe' to use int16_t in replace of __int16?
Also, if im not mistaken could i just use unsigned short int for a 16 bit integer rather than using int16_t or __int16?
They will be the same.
People used to define their own fixed width types before the standard ones came out. Just use a typedef - that's what they are for.
int16_t and __int16 should both be signed 16-bit integers. Substituting one for the other should be fine. unsigned short int is completely different. It is unsigned rather than signed and it isn't guaranteed to be 16 bits. It could end up being a different size.

Is `short` the same as `int` in C++?

I've looked at some answers that use short in C#, but I'm not sure if they really answer my question here. Is short in C++ another name for int? I know you can make short int, which seems to be able to handle a lot of values but I'm still starting out, so obviously if it's short it's not a lot of values. But in this code snippet here:
short lives,aliensKilled;
it doesn't use int short, it just uses short. So I guess my question is, can I just use short as a replacement for int if I'm not going under -32,768 or over 32,767?
Also, is it okay to just replace short with int, and it won't really mess with anything as long as I change the appropriate things? (Btw lives and aliensKilled are both variable names.)
In C++ (and C), short, short int, and int short are different names for the same type. This type is guaranteed to have a range of at least -32,767..+32,767. (No, that's not a typo.)
On most modern systems, short is 16 bits and int is 32 bits. You can replace int with short without ill effects as long as you don't exceed the range of a short. On most modern systems, exceeding the range of a short will usually result in the values wrapping around—this behavior is not guaranteed by the standard and you should not rely on it, especially now that common C++ compilers will prune code paths that contain signed integer overflow.
However, in most situations, there is little benefit to replacing int with short. I would only replace int with short if I had at least thousands of them. There's not always a benefit, by using short you can reduce the memory used and the bandwidth required, but you can potentially increase the number of CPU cycles required to convert from short to int (a short is always "promoted" to int when you do arithmetic on it).
short int, int short and short are all synonymous in C and C++.
These work like int, but the range is smaller (typically, but not always) 16 bit. As long as none of the code relies on the transitions when the number "wraps around" due to it being 16 bits (that is, no calculation goes above the highest value (SHORT_MAX) or below the lowest value (SHORT_MIN)), using a larger type (int, long) will work just fine.
C++ (and C# and Objective-C and other direct descendants of C) have a quirky way of naming and specifying the primitive integral types.
As specified by C++, short and int are simple-type-specifiers, which can be mixed and matched along with the keywords long, signed, and unsigned in any of a page-full of combinations.
The general pattern for the single type short int is [signed] short [int], which is to say the signed and int keywords are optional.
Note that even if int and short are the same size on a particular platform, they are still different types. int has at least the same range as short so it's numerically a drop-in replacement, but you can't use an int * or int & where a short * or short & is required. Besides that C++ provides all kinds of machinery for working with types… for a large program written around short, converting to int may take some work.
Note also that there is no advantage to declaring something short unless you really have a reason to save a few bytes. It is poor style and leads to overflow errors, and can even reduce performance as CPUs today aren't optimized for 16-bit operations. And as Dietrich notes, according to the crazy way C arithmetic semantics are specified, the short is upcast to int before any operation is performed and then if the result is assigned back to a short, it's cast back again. This dance usually has no effect but can still lead to compiler warnings and worse.
In any case, the best practice is to typedef your own types for whatever jobs you need done. Always use int by default, and leverage int16_t, uint32_t from <stdint.h> (<cstdint> since C++11), etc instead of relying on platform-dependent short and long.
Yes, short is equivalent to short int, and it uses at least 2 bytes, but if you stay in the range you can replace int with short without any problem.
Yes, you can use it. short = short int. Signed -32768 to 32767 and unsigned 0 to 65535 .
short can at max be two bytes long. On machines where int is two bytes, short and int have same range i.e. -32767 to +32767. For most of the new platforms, int is 4 bytes, catering to much larger range of values.
I recommend to go for explicit declaration such as int16_t for short and int32_t for int to avoid any confusion.
Also notice that for the following code:
short a = 32767;
a++;
cout << a;
It will print -32768.
So, if you go over its limit, it will "go back" with the counting.

Should I use "unsigned" every time i know I'm processing unsigned values?

Often values are known to be positive. For example TCP/UDP sequence number is always positive value. Both int and unsigned int are big enough to store even the biggest sequence number so I can use any of these types. There are many other examples when values are known to be positive.
Are there any reasons to use unsigned type when capacity of regular signed type is enough (and often more than enough)?
Personally I tend to use regular types because:
int is probably a little bit more readable than uint or unsigned int
I don't need to include extra headers for UINT etc.
I will avoid extra casts somewhere further in the program
Reasons to use unsigned type I can imagine:
help compiler generated better code?
help another programmer to understand that variable is unsigned
avoid possible bugs (for example when int is assigned to UINT compiler likely will generate compile-time error and we should check that value we assign is not negative)
One reason is that comparing signed and unsigned numbers can lead to surprising results. In C and (I think) C++, comparing signed and unsigned numbers causes the signed number to be interpreted as unsigned. If the signed value happens to be negative, reading it as unsigned will give a LARGER value than any unsigned number, which is not what you want. See this question for an example in Objective-C, which uses the same conversion rules as C.

What is practiced in C++ to use for byte manipulation uint8 or char?

I am coming from Java to C++ and I need something similar to byte[] from Java. I can use std::vector<> for easy array like manipulation but I need answer what is practiced in C++ to use for byte manipulation uint8 or char ? ( I have lot off packing bigger integers in arrays with & 0xff and >> number so it need to be quick)
Assuming that uint8 is an 8 bit unsigned integer type, the main difference on a "normal" C++ implementation is that char is not necessarily unsigned.
On "not normal" C++ implementations, there could be more significant differences -- char might not be 8 bits. But then, what would you define uint8 to be on such an implementation anyway?
Whether the sign difference matters or not depends how you're using it, but as a rule of thumb it's best to use unsigned types with bitwise operators. That said, they both get promoted to int in bitwise & anyway (again on a "normal" C++ implementation) and it really doesn't matter for &, it doesn't cause surprises in practice. But using << on a negative signed value results in undefined behavior, so avoid that.
So, use an unsigned type. If the most convenient way for you to write that is uint8, and you know that your code deals in octets and will only run on systems where char is an octet, then you may as well use it.
If you want to use a standard type, use unsigned char. Or uint8_t in order to deliberately prevent your code compiling on "not normal" implementations where char is not an octet.
C++ reserved words are char, signed char, and/or unsigned char. uint8 is probably a typedef synonym for unsigned char.

Can someone explain how the signedness of char is platform specific?

I recently read that the differences between
char
unsigned char
and
signed char
is platform specific.
I can't quite get my head round this? does it mean the the bit sequence can vary from one platform to the next ie platform1 the sign is the first bit, platform2 the sign could be at the end? how would you code against this?
Basically my question comes from seeing this line:
typedef unsigned char byte;
I dont understand the relevance of the signage?
Let's assume that your platform has eight-bit bytes, and suppose we have the bit pattern 10101010. To a signed char, that value is −86. For unsigned char, though, that same bit pattern represents 170. We haven't moved any bits around; it's the same bits, interpreted two different ways.
Now for char. The standard doesn't say which of those two interpretations should be correct. A char holding the bit pattern 10101010 could be either −86 or 170. It's going to be one of those two values, but you have to know the compiler and the platform before you can predict which it will be. Some compilers offer a command-line switch to control which one it will be. Some compilers have different defaults depending on what OS they're running on, so they can match the OS convention.
In most code, it really shouldn't matter. They are treated as three distinct types, for the purposes of overloading. Pointers to one of those types aren't compatible with pointers to another type. Try calling strlen with a signed char* or an unsigned char*; it won't work.
Use signed char when you want a one-byte signed numeric type, and use unsigned char when you want a one-byte unsigned numeric type. Use plain old char when you want to hold characters. That's what the programmer was thinking when writing the typedef you're asking about. The name "byte" doesn't have the connotation of holding character data, whereas the name "unsigned char" has the word "char" in its name, and that causes some people to think it's a good type for holding characters, or that it's a good idea to compare it with variables of type char.
Since you're unlikely to do general arithmetic on characters, it won't matter whether char is signed or unsigned on any of the platforms and compilers you use.
You misunderstood something. signed char is always signed. unsigned char is always unsigned. But whether plain char is signed or unsigned is implementation specific - that means it depends on your compiler. This makes difference from int types, which all are signed (int is the same as signed int, short is the same as signed short). More interesting thing is that char, signed char and unsigned char are treated as three distinct types in terms of function overloading. It means that you can have in the same compilation unit three function overloads:
void overload(char);
void overload(signed char);
void overload(unsigned char);
For int types is contrary, you can't have
void overload(int);
void overload(signed int);
because int and signed int is the same.
It's more correct to say that it's compiler-specific and you should not count on char being signed or unsigned when using char without a signed or unsigned qualifier.
Otherwise you would face the following problem: you write and debug the program assuming that char is signed by default and then it is recompiled with a compiler assuming otherwise and the program behaviour changes drastically. If you rely on this assumption only once in a while in your code you risk facing unintended behaviour in some cases which are only triggered in your program under specific conditions and are very hard to detect and debug.
Perhaps you are referring to the fact that the signedness of char is compiler / platform specific. Here is a blog entry that sheds some light on it:
Character types in C and C++
Having a signed char is more of a fluke of how all base variable types are handled in C, generally it is not actually useful to have negative characters.
a signed char is always 8 bit and has always the signed bit as the last bit.
an unsigned char is always 8 bit and doesn't have a sign bit.
a char is as far as I know always unsigned. Any compiler defaulting to a signed char will face a lot of incompatible programs.