uint32_t, int_t notation for representing variable size - c++

This question only is about the notation selection reason.
To prevent bugs it is essential to mention the variable size in bits like
uint32_t VariableA; // uint32_t has been type defined for architecture whose int size is 32 bit.
int16_t VariableB;
instead of using only type specifiers like
int VariableName;
The question here is why is _t used in the uint32_t instead of only uint32. Where did this _t come that has been seen appended in the typedef?

The names were taken from the POSIX specification, which was widely used before C and C++ standardised the names of fixed-size integer types. POSIX uses a convention of appending _t to most type names.

The _t convention comes from the early days of UNIX. Following suit, most (or all) aliases to scalar types and many struct types in Posix are named as such, and some such types are even standardized in C itself.
Posix furthermore reserves all names suffixed with _t in the C++ global namespace (or for C, just in general).
C++ does not introduce any new _t names to my knowledge, and best-practice use of the C++ standard library only introduces names into the std namespace.
At some point in the future, it is anticipated/hoped that Posix will be sandboxed in the posix namespace.
In any case, best practice is to keep all your interface typedefs in your own namespace, and once you've done that, naming aliases to scalar types with _t is quite a reasonable policy. The benefit is that C++ is often sensitive to whether two name refer to types that are really different (but maybe behave similarly) or they are really aliases to the same thing. _t is obviously an alias to something simple.

_t basically denotes a type name. Therefore, you would be ill-advised to end variable or function names with _t since it could cause some confusion and even undefined behaviour(depending on compiler etc.)
Addendum
POSIX systems define a lot of extra type names ending in _t, and reserves the suffix for the implementation. Therefore when working on POSIX-related systems, defining your own type names with the convention is ill-advised and can lead to undefined behaviour

Related

Is there automatic name lookup for enumerators in c++?

As for as I know, currently in c++ there is no support for this.
For example,
class C{
struct{
enum {defaulted, opt1, opt2, ...} flag1;
enum {defaulted, optA, optB, ...} flag2;
} flags;
...
};
Now suppose we have C obj, to use the flag one would do
obj.flags.flag1 = obj.flags.opt1;
which is unnecessarily verbose.
However as the type of obj.flags.flag1 is known, in theory the compiler could lookup the name opt1 in that scope and save some typing.
Because the flags are not used anywhere else, it is preferred not to give names to the types (in fact it is difficult to come up with appropriate names). using enum syntax in c++20 does not solve this, because: it 1) requires the enum types to be named; 2) using multiple enums may lead to name collision, as shown here, since both enums have a defaulted member.
What will be the difficulties to implement this? Has this been proposed to the C++ standard committee and/or implemented in some compiler?
There could easily be an object named opt1 that could be converted to the appropriate enumeration type. It's better for name lookup to behave consistently rather than make special cases based on the types of other operands (partly because types are usually determined after name lookup).

C++ - Significance of local names for types

I recently read up how classes are allowed to define their own local names for types. One of the famous examples being size_type, provided almost by all STL containers. It was also mentioned that doing so helps hide implementation details from the user of the class. I am not quite sure how this is the case.
What are some examples where defining local names for types might be useful and how doing so hides implementation details?
Please provide some examples where defining local names for types might be useful and how it hides implementation details.
its more usefull when you use templated algorithms or containers, which might assume that your type has such type alias. So even if you modify type for size_type - i.e. change for some reason from size_t to int, then your type will still work with those algorithms / containers.
Otherwise, presence of size_type are required by standard when you for example implement your own allocator.
Suppose you have a program where you define several variables of type size_type and that it is defined somewhere as an int.
Then, upon analysis and reflection, you realize that the variables never assume values igger than 10 thousand. Therefore, the 32 bits used to allocate each of these variables are somewhate an overkill. In this case, you can redefine size_type as being of short type, instead of int. Therefore you will end up saving some memory.
Regarding the examples, you can check clock_t, char16_t, char32_t, wchar_t, true_type and false_type.

C++ type suffix _t, _type or none

C++ sometimes uses the suffix _type on type definitions (e.g. std::vector<T>::value_type),
also sometimes _t (e.g. std::size_t), or no suffix (normal classes, and also typedefs like std::string which is really std::basic_string<...>)
Are there any good conventions on when to use which name?
As #MarcoA.'s answer correctly points out, the suffix _t is largely inherited from C (and in the global namespace - reserved for POSIX).
This leaves us with "no suffix" and _type.
Notice that there is no namespace-scope name in std ending in _type*; all such names are members of classes and class templates (or, in the case of regex-related types, of a nested namespace which largely plays a role of a class). I think that's the distinction: types themselves don't use the _type suffix.
The suffix _type is only used on members which denote types, and moreover, usually when they denote a type somewhat "external" to the containing class. Compare std::vector<T>::value_type and std::vector<T>::size_type, which come from the vector's template parameters T and Allocator, respectively, against std::vector<T>::iterator, which is "intrinsic" to the vector class template.
* Not entirely true, there are a few such names (also pointed out in a comment by #jrok): common_type, underlying_type, is_literal_type, true_type, false_type. In the first three, _type is not really a suffix, it's an actual part of the name (e.g. a metafunction to give the common type or the underlying type). With true_type and false_type, it is indeed a suffix (since true and false are reserved words). I would say it's a type which represents a true/false value in the type-based metaprogramming sense.
As a C heritage the _t (that used to mean "defined via typedef") syntax has been inherited (they're also SUS/POSIX-reserved in the global namespace).
Types added in C++ and not present in the original C language (e.g. size_type) don't need to be shortened.
Keep in mind that to the best of my knowledge this is more of an observation on an established convention rather than a general rule.
Member types are called type or something_type in the C++ standard library. This is readable and descriptive, and the added verbosity is not usually a problem because users don't normally spell out those type names: most of them are used in function signatures, then auto takes care of member function return types, and in C++14 the _t type aliases take care of type trait static type members.
That leads to the second point: Free-standing, non-member types are usually called something_t: size_t, int64_t, decay_t, etc. There is certainly an element of heritage from C in there, but the convention is maintained in the continuing evolution of C++. Presumably, succinctness is still a useful quality here, since those types are expected to be spelled out in general.
Finally, all the above only applies to what I might call "generic type derivation": Given X, give me some related type X::value_type, or given an integer, give me the 64-bit variant. The convention is thus restricted to common, vocabulary-type names. The class names of your actual business logic (including std::string) presumably do not warrant such a naming pattern, and I don't think many people would like to have to mangle every type name.
If you will, the _t and _type naming conventions apply primarily to the standard library and to certain aspects of the standard library style, but you do not need to take them as some kind of general mandate.
My answer is only relevant for type names within namespaces (that aren't std).
Use no suffix usually, and _type for enums
So, here's the thing: the identifier foo_type can be interpreted as
"the identifier of the type for things which are foo's" (e.g. size_type overall_size = v1.size() + v2.size();)
"the identifier of the type for things which are kinds, or types, of foo" (e.g. employment_type my_employment_type = FIXED_TERM;)
When you have typedef'ed enums in play, I think you would tend towards the second interpretation - otherwise, what would you call your enum types?
The common aversion to using no suffix is that seeing the identifier foo is confusing: Is it a variable, a specific foo? Or is it the type for foos? ... luckily, that's not an issue when you're in a namespace: my_ns::foo is obviously a type - you can't get it wrong (assuming you don't use global variables...); so no need for a prefix there.
PS - I employ the practice of suffixing my typedef's within classes with _type (pointer_type, value_type, reference_type etc.) I know that contradicts my advice above, but I somehow feel bad breaking with tradition on this point.
Now, you could ask - what happens if you have enums within classes? Well, I try to avoid those, and place my enum inside the surrounding namespace.

Does the "type" of a struct change from computer to computer?

Let's assume I have this code;
class Ingredients{
public:
Ingredients(int size,string name);
int getsize();
private:
string name;
int size;
};
struct Chain{
Ingredients* ing;
Chain* next;
}
And in my main;
int main()
{
cout<<typeid(Chain).name()<<endl;
cout<<typeid(Chain->ing).name()<<endl;
cout<<typeid(Chain->next).name()<<endl;
}
my headers are;
#include <iostream>
#include <typeinfo>
using namespace std;
and finally outputs;
P8Chain
P12Ingredients
P8Chain
so my question is, will this types are reliable for using it in a code? If the types are changing (because of the P8 and P12 things I am not sure it would be the same) from computer to comp. this types wouldn't be reliable. What are your opinions?
Also they are not changing on every run.
They depend on your compiler, so don't use them inside your code.
The C++ standard says the following concerning typeid (section 5.2.8):
The result of a typeid expression is an lvalue of static type const std::type_info and dynamic type const std::type_info or const name where name is an implementation-defined class derived from std::type_info.
What you can do if you want some sort of RTTI is
if (typeid(myobject) == typeid(Chain)) {
do_something();
}
It depends on what you mean by "type". The more or less standard definition of type is the set of values and operations the type can take, and this will change from one machine to the next, because the size of int will change, or the maximum length of a string. On the other hand, there is a very real sense that type is what the compiler and the C++ standard consider it to be, which very roughly would correspond to, or at least be identified by the scoped name. Finally, the std::type_info::name() function is seriously underspecified. At best, it can be useful for debugging (e.g. logging the actual derived class a function was called with), and not all compilers provide even that. As far as the standard is concerned, a compiler could always return an empty string, and still be conform.
According to the standards the name() is implementation defined (as well as according to Stroustrup book - see p 415 on 3th edition)
The word "type" has multiple meanings.
In terms of type theory, a C++ struct doesn't really define a type at all.
More usefully, the C++ language standard talks about types in a way that can be taken rigorously, even if it never quite rigorously defines the term. In those terms, the struct declaration does define a unique and consistent type.
Maybe even more usefully, to your C++ compiler (and C linker), a type is represented by things like a memory layout, a mangled name, a list of member names and types, pointers to special and normal member functions, possibly pointers to vtable and/or rtti info, etc. This will not be the same from implementation to implementation. Between builds with the same implementation, some details (like where the pointers point) may change even if no relevant code changes, but you could probably define a useful subset of information that you could usefully call a "type" that doesn't change.
Beyond that, the type_info instance defined by section 18.5.1 of the standard cannot change within the bounds of what's explicitly defined, and the result of typeid as defined by section 5.2.8 as to be that instance or a compatible object that still compares equal to it. So, it sounds to me like, if it were possible to load up the type_info instances from two different runs at the same time, operator== would have to return true. However, it's not actually possible to load up type_info instances from two different runs (there's no requirement that they be serializable in any way, for example), so this may not be relevant.
Finally, the name displayed by typeid().name(), as defined by section 18.5.1, is just any implementation-defined NTBS. It could change between builds, runs, even calls within the same run. It could always be empty. Practically, it'll often be something vaguely useful for debugging, but that isn't guaranteed—and, even if it were, that wouldn't help, because "vaguely useful for debugging" doesn't have to mean "unique within a run and persistent across runs".
If you're asking about a specific compiler, the documentation for the compiler may give stricter guarantees than the standard requires. For example, I believe that on various platforms g++ guarantees that it'll use the C++ ABI defined at CodeSourcery, and will not change ABI versions within minor compiler versions, and will use the mangled names defined in the ABI as the type_info names. This means taking the binary to another computer won't affect the names, and even recompiling the source on another computer with the same platform and g++ version won't affect the names.

C++ - Is string a built-in data type?

In C++, is string a built-in data type?
Thanks.
What is the definition of built-in that you want to use? Is it built-in the compiler toolset that you have yes, it should. Is it treated specially by the compiler? no, the compiler treats that type as any user defined type. Note that the same can probably be applied to many other languages for which most people will answer yes.
One of the focuses of the C++ committee is keeping the core language to a bare minimum, and provide as much functionality as possible in libraries. That has two intentions: the core language is more stable, libraries can be reimplemented, enhanced... without changing the compiler core. But more importantly, the fact that you do not need special compiler support to handle most of the standard library guarantees that the core language is expressive enough for most uses.
Simpler said in negated form: if the language required special compiler support to implement std::string that would mean that users don't have enough power to express that or a similar concept in the core language.
It's not a primitive -- that is, it's not "built in" the way that int, char, etc are. The closest built-in string-like type is char * or char[], which is the old C way of doing stringy stuff, but even that requires a bunch of library code in order to use productively.
Rather, std::string is a part of the standard library that comes with nearly every modern C++ compiler in existence. You'll need to #include <string> (or include something else that includes it, but really you should include what your code refers to) in order to use it.
If you are talking about std::string then no.
If you are talking about character array, I guess you can treat it as an array of a built in type.
No.
Built-in or "primitive" types can be used to create string-life functionality with the built-in type char. This, along with utility functions were what was used in C. In C++, there is still this functionality but a more intuitive way of using strings was added.
The string class is a part of the std namespace and is an instantiation of the basic_string template class. It is defined as
typedef basic_string<char> string;
It is a class with the ability to dynamically resize as needed and has many member functions acting as utilities. It also uses operator overloading so it is more intuitive to use. However, this functionality also means it has an overhead in terms of speed.
Depends on what you mean by built-in, but probably not. std::string is defined by the standard library (and thus the C++ standard) and is very universally supported by different compilers, but it is not a part of the core language like int or char.
It can be built-in, but it doesn't have to be.
The C++ standard library has a documented interface for its components. This can be realized either as library code or as compiler built-ins. The standard doesn't say how it should be implemented.
When you use #include <string> you have the std::string implementation available. This could be either because the compiler implements it directly, or because it links to some library code. We don't know for sure, unless we check each compiler.
None of the known compilers have chosen to make it a built-in type, because they didn't have to. The performance of a pure library implementation was obviously good enough.
No. It's part of standard library.
No, string is a class.
Definitely not. String is a class from standard library.
char *, or char[] are built-in types, but char, int, float, double, void, bool without any additions (as pointers, arrays, sign or size modifiers - unsigned, long etc.) are fundamental types.
No. There are different imlementations (eg Microsoft Visual C++), but char* is the C++ way of representing strings.