Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do you need 'int' in C++?

Tags:

c++

int

I do realize the title may sound silly at first, but please, bear with me for a moment. :)

Ever since I've started using size_t and ptrdiff_t, I haven't had a use for int, as far back as I can remember.

The only integer data types I remember using recently fall into one of these categories:

  1. (Unsigned) integers associated with an index into some in-memory data structure (e.g. vector).
    Almost always, the most appropriate type for this is size_t (or ...::size_type, if you're going the extra mile).
    Even if the integer doesn't actually represent an index, often times it's still associated with some index, so size_t is still appropriate.

  2. Signed versions of size_t. In many cases, the most suitable type for this seems to be ptrdiff_t, because often times when you need this, you're working with iterators -- and hence size_t and ptrdiff_t are both appropriate for them.

  3. long. I occasionally need this for _InterlockedIncrement (reference counting).

  4. (unsigned) long long, used for holding file sizes.

  5. unsigned int or unsigned long, useful for "counting" purposes (e.g. every 1 million iterations, update the UI).

  6. unsigned char for raw byte-level access to memory.
    (Side note: I never found a use for signed char either.)

  7. intptr_t and uintptr_t for occasionally storing operating system handles, pointers, etc.

One particular aspect of int that's important is that you shouldn't overflow it (since it's undefined behavior), so you can't even use it reliably for counting -- especially if your compiler defines it to be 16 bits.

So when, then, should you use int (aside from when a dependency of yours already requires it)?
Is there any real use for it nowadays, at least in newly written, portable code?

like image 699
user541686 Avatar asked Dec 18 '12 05:12

user541686


People also ask

Why do we use int in C?

An int variable contains only whole numbers Int, short for "integer," is a fundamental variable type built into the compiler and used to define numeric variables holding whole numbers. Other data types include float and double. C, C++, C# and many other programming languages recognize int as a data type.

Is int main necessary in C?

So the difference is, in C, int main() can be called with any number of arguments, but int main(void) can only be called without any argument. Although it doesn't make any difference most of the times, using “int main(void)” is a recommended practice in C.

Why do we need int?

int main means that the main function returns an integer value.so in case of integer, we use int in C programming. Int keyword is used to specify integer datatype . It's size may be 16,32,64 bits depending on the machine or further short /long types. int is a datatype which is used to represent integer values.

Why do we use int before main in C?

Because the main function returns type integer,i.e either '1/program ran successfully' or '0/program compile error '.


2 Answers

How about the most important reason of all - readability. (and simple math)

long weeklyHours = daysWorked * hoursPerDay;

"Okay... but then again, how much can a human actually work per week that we need a long"

size_t weeklyHours = daysWorked * hoursPerDay;

"Wait... are we using weeklyHours to iterate over a vector?"

unsigned int weeklyHours = daysWorked * hoursPerDay;

"Clear enough." - possible source for errors if either can be negative (part of the logic - it could be a way to account for time off or leave, not important)

int weeklyHours = daysWorked * hoursPerDay;

"Okay, simple enough. I get what this is doing."

like image 71
Luchian Grigore Avatar answered Oct 17 '22 13:10

Luchian Grigore


Luchian has some excellent readability points, to which I'll add some technical ones:

  • the compiler's expected to pick a size for int that's efficient to deal with, whereas long might not be (risks more CPU cycles per operation, more bytes of machine code, more registers needed etc.)
  • using signed types can eliminate some errors, such as:
    • abs(a - b) looks right mathematically but doesn't give the intuitive result when b > a and they're unsigned
    • int second_delta = (x.seconds - y.seconds) + (x.minutes - y.minutes) * 60;
    • if (pending - completed > 1) kick_off_threads()
  • when needing an integral sentinel value -1 is often used: for unsigned types this will be converted to the largest possible value, but that can lead to misunderstandings and coding errors (e.g. if (x >= 0) test for non-sentinel)

Also, there's a lot of scope for implicit conversions between signed and unsigned integers - it's important to understand that unsigned types rarely help enforce a "non-negative" invariant: if that's part of the appeal, you're better off writing a class with constructor and operators enforcing the invariant.

On the readability side, int denotes a general need for a number that clearly spans the problem domain - it may be excessive but it's known cheap in machine code ops and CPU cycles so is the go-to type for general integral storage. If you start using say unsigned char to store someone's age - not only does it not play well with operator<<(std::ostream&...), but it begs questions like "was there some need to conserve memory here?" (especially confusing for stack-based variables), "is there some intention to treat this as binary data for I/O or IPC purposes?", or even "is it a known single-digit age stored in ASCII?". If something's likely to end up in a register anyway, int is a natural sizing.

like image 43
Tony Delroy Avatar answered Oct 17 '22 11:10

Tony Delroy