How to detect llvm::ConstantInt is signed or unsigned? - llvm

how could I detect llvm::ConstantInt is signed or unsigned ?
Which API should I use?

Related

Why `std::countl_one` doesn't work for UTF character types?

C++20 added std::countl_one. According to cppreference.com:
This overload participates in overload resolution only if T is an unsigned integer type (that is, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, or an extended unsigned integer type).
Thus, it doesn't work for any of the UTF character types (char8_t, char16_t, char32_t) or wchar_t. That function would be useful for implementing UTF encoding/decoding. What is the exclusion for? I guess one could cast to some other integer type before calling that function, but that still seems like an unnecessary extra step.
std::countl_one et al. are designed to work on unsigned types. In the proposal P0553R4: Bit Operations we see this small blurb that confirms it:
For now, it is intentional that the "unsigned" requirement excludes std::byte or char, even on platforms where char is unsigned.
Given this requirement, this necessarily excludes signed char types like char8_t.

Is there a pratical reason for defining a uint8_t as unsigned short?

Creating an Arduino project in Visual studio, a project file named .nameProject.vsarduino.h is automatically created, in which the following lines define the uint8_t and int8_t type:
typedef unsigned short uint8_t;
typedef short int8_t;
I've seen that uint8_t is in fact a type that contains at least 8 bits.
I wonder if this definition could bring a lot of mistakes, for example managing streams of bytes used for i2c communication for which the field lengths are typically defined in terms of bytes.
Many library functions, in fact, use indifferently uint8_t or unsigned char, but in this practical case this is not the same type.
Any comment and/or suggestion is appreciated.
I've seen that uint8_t is in fact a type that contains at least 8 bits.
Where? The fixed width types in <cstdint> are provided specifically to expose types whose width is fixed at exactly the number of bits mentioned in the type name. Not bounded below. So uint8_t must have exactly 8 bits.
If you just want an unsigned type whose width is at least 8 bits, use unsigned char.
Many library functions, in fact, use indifferently uint8_t or unsigned char, but in this practical case this is not the same type.
This is fine for a platform-specific library that knows its platform's unsigned char is exactly 8 bits, and then it is the same type.
This, on the other hand:
typedef unsigned short uint8_t;
is always guaranteed to be wrong. Both short and unsigned short are required to be at least 16 bits.
If the platform can't expose a type with exactly 8 bits, it shouldn't provide an 8-bit fixed-width type at all.

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.

What is the difference between signed and normal short

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.

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.