9

I'm an electrical engineer turned to computer scientist. It's really hard for me to understand why in C++ there are so many things that are almost the same but not completely the same. An example is short vs int vs unsigned int vs size_t vs long int vs long long int vs uint8_t (I don't know if there is any additional way to designate an integer). It seems that it makes the language unnecessarily complicated.

Could or should size_t be replaced or does it have any feature impossible to use in another way?


[EDIT]

After the helpful answers, there is something that I still don't fully see. size_t is useful in terms of portability and performance as several persons suggested. But how helpful, is there a quantitative way or numerical evidence to measure the advantages over having just only int and retire all its brothers???

hoaphumanoid
  • 977
  • 1
  • 9
  • 25
  • The native types (like `int`, `short` etc) are there partly because that's what C had, and C++ was originally just a preprocessor that generated C code, the other part is because it makes it much easier to code "close to the metal". The type-aliases (like `size_t`) is to make code more legible and is more to show intent. Using `size_t` you say that "this is a size", so it's more for the programmers and less for the need of the compiler. – Some programmer dude Jan 01 '16 at 19:55
  • 2
    Possible duplicate of [unsigned int vs. size\_t](http://stackoverflow.com/questions/131803/unsigned-int-vs-size-t), or any other size_t question in the "related" section. – Zeta Jan 01 '16 at 19:55
  • 3
    Replaced with .... what? – Lightness Races in Orbit Jan 01 '16 at 20:02
  • @JoachimPileborg and Lightness could it be replaced by int (or any of the int cousins???) – hoaphumanoid Jan 01 '16 at 20:05
  • @HoapHumanoid That's what `size_t` is, a type alias for some unsigned integer. But details vary across platforms (as you may know, unlike Java, C and C++ do not impose strict bounds on the fundamental type sizes), and I'd very much prefer to use `size_t` instead of checking whether I need to use e.g. `unsigned long` or `unsigned long long` instead. – vsoftco Jan 01 '16 at 20:09
  • @Zeta I'm not asking about the difference about `unsigned int` and `size_t`, I'm asking if we could replace it and why yes or no. Please read my question and the edit I did – hoaphumanoid Jan 01 '16 at 20:34
  • 1
    One of the brothers of int is char, which is a smallish integer type. Another one is long long, which is at least 64 bits. It seems like neither of those could be reasonably replaced with an int, of whatever size. Do you really want to bulk up character strings by storing each character in eight bytes? If not, are you prepared to say that there is no integer type large enough to hold the size of your memory, with the result that you can only use a fraction of it for a single object? The resulting model might have fewer moving parts, but I'd say they'd be a lot more annoying to move. – rici Jan 01 '16 at 21:31
  • @rici I was sure there was some more brothers hehehe. Yes you are right. However, isn't a way to efficiently allocate the enough quantity of memory and not need to have so many brothers? – hoaphumanoid Jan 01 '16 at 21:35
  • 3
    @HoapHumanoid: You need to give the programmer a way to express the requirements, no? Those might be algorithmic (i.e. knowing how big the numbers will be) or they might be environmental (i.e. the size of an object on this platform; the size of a character on this platform). C/C++ offer both options, plus some somewhat subjective ones ("biggish", "smallish"). Under the hood, there are only a few types, since most of the definitions are aliases. But the aliases are what let me just say what I need, rather than making me research every architecture I'm going to use. – rici Jan 01 '16 at 21:42

2 Answers2

16

std::size_t is a typedef for an unsigned fundamental type, and it should be able to represent any possible index/size in your program (technically, it is also the result of the sizeof operator). Its underlying fundamental type may differ on different implementations, and because you want portability, you use std::size_t and don't care anymore whether it's a unsigned long int or unsigned long long int etc.

std::size_t does not use any feature impossible to use in another way, it is just a convenient type alias and nothing more.

In response to the OP edit

@HoapHumanoid The edit is not a very good question for StackOverflow, as it is a matter of personal interpretation/preference. Of course you can have only one numeric type, or fixed-size types, however when you want to squeeze as much performance out of your processor, you better have many, each capable of representing a specific range, depending on the physical platform. Because computer architectures are vastly different, each architecture will impose its own size for e.g. int, long etc. When you combine this issue with portability, then size_t emerges naturally. What else would you use in a generic function that e.g. is guarantee to allocate as much memory as possible on every possible implementation? Would you use int to pass the number of bytes? Or maybe long int? You need to read the compiler manual, check the appropriate type etc, then use it. That's what the C++ implementation does for you, defines an appropriate such type.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • But could we then use typedef instead and define something like my_wonderful_int??? And kill size_t?? Not kill it poor guy, just retire it XDDD – hoaphumanoid Jan 01 '16 at 20:00
  • 1
    @HoapHumanoid Yes you can, but `size_t` is defined so that everyone knows it exists and uses it. Otherwise other programmers won't know about your *wonderful_int*. A type guaranteed to have the same name on all platforms and also guaranteed to store any possible index is super useful in terms of portability. For example, on my machine I may have `typedef unsigned long long size_t`, whereas on yours you may have `typedef unsigned long size_t`. Without this `typedef`, you'd need to know the correct size on each platform, which becomes a pain. – vsoftco Jan 01 '16 at 20:02
  • OK, and what if we kill (retire hehe) not only size_t but also all is cousins and use only int?. Maybe I should ask this in another question. I'm gonna do it – hoaphumanoid Jan 01 '16 at 20:14
  • @HoapHumanoid You're going to run into serious issues, as `int` may not be large enough. Then you're back to square one, trying to come up with a type that is large enough, and with the same name on each platform. Another option is to force C and C++ to use fixed sizes for the fundamental types, like Java, but I bet this is not going to happen due to various reasons, such as portability, performance, back portability etc. – vsoftco Jan 01 '16 at 20:16
  • vsoftco I just edit my question following what we are talking – hoaphumanoid Jan 01 '16 at 20:32
  • ok but I'm not talking about personal interpretation or preference. Many people say that you can improve the performance, but I'm asking for numerical evidence, like a benchmark or something. Do you know about this kind of evidence in the matter of int and similars??? – hoaphumanoid Jan 01 '16 at 20:40
  • @HoapHumanoid Don't have an immediate link to such benchmarks, although I'm sure they exist. I'm not an expert in computer architectures, only read a bit about those issues. – vsoftco Jan 01 '16 at 20:43
2

You forgot long long int, most of the unsigned versions, uint8_t and friends, and probably some more. :-)

In some languages the size of the integer types is fixed. C++ is not one of those; lots of flexibility is given to the programmer to allow balancing performance against size and range.

But size_t is extremely useful. It is guaranteed to be able to hold the size of any object, or any valid array index. Not having it would make writing portable yet efficient programs much more difficult.

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64
  • I knew there were more ways to express int hehehe. Regarding what you said about to hold the size of any object. Can't we do this with any of the other 9 types of integer?? – hoaphumanoid Jan 01 '16 at 20:03
  • 2
    Well, `unsigned. int` might be too small on a 64 bit system, and `unsigned long long` would be too big on a 32 bit system. So on any given system at least one of the other types would work, but exactly which one would vary on different systems. – Alan Stokes Jan 01 '16 at 20:06