Type of Integer Literals Not Int by Default

Type of integer literals not int by default?

As far as C++ is concerned:

C++11, [lex.icon] ¶2

The type of an integer literal is the first of the corresponding list in Table 6 in which its value can be represented.

And Table 6, for literals without suffixes and decimal constants, gives:

int
long int
long long int

(interestingly, for hexadecimal or octal constants also unsigned types are allowed - but each one come after the corresponding signed one in the list)

So, it's clear that in that case the constant has been interpreted as a long int (or long long int if long int was too 32 bit).

Notice that "too big literals" should result in a compilation error:

A program is ill-formed if one of its translation units contains an integer literal that cannot be represented by any of the allowed types.

(ibidem, ¶3)

which is promptly seen in this sample, that reminds us that ideone.com uses 32 bit compilers.


I saw now that the question was about C... well, it's more or less the same:

C99, §6.4.4.1

The type of an integer constant is the first of the corresponding list in which its value can be represented.

list that is the same as in the C++ standard.


Addendum: both C99 and C++11 allow also the literals to be of "extended integer types" (i.e. other implementation-specific integer types) if everything else fails. (C++11, [lex.icon] ¶3; C99, §6.4.4.1 ¶5 after the table)

If default type of Java integer literal is type int, why does these assignment statements compile?

The compiler knows that the numbers you are using is small enough and can therefore fit into the given space. If you do short d = 1000000; it cannot fit in a short and will give you an error.

Why is the default type of Java integer literals int instead of long?

This behavior is by design1 and is codified in the JLS: Java Language Specification.

First, note that this is not related to widening which is why the (valid) integer-literal is promoted to a long value. Instead, this is related to the very specification of the int literal:

It is a compile-time error if a hexadecimal, octal, or binary int literal does not fit in 32 bits.

The smallest and largest signed 32-bit integer values are -2147483648 and 2147483647, respectively.


1I care not speculate on why it works this way, and languages like C# have different rules.

What is the default type of integral literals represented in hex or octal in C++?

The type of the integral literal is defined less by whether it is a hexadecimal literal, a decimal literal, or an octal literal and more by the value of the literal.

Table 6 — Types of integer constants, in Section 2.14.2 of the C++11 Standard lists the order of types that will be used to capture an integral literal.

The main difference between decimal literals and hexadecimal and octal literals is that the order of types of decimal literals is int, long, long long while the order of types of hexadecimal and octal literals is int, unsigned int, long, unsigned long, long long, and unsigned long long.

Are integer literals considered unsigned?

A decimal integer literal is of the first type where it can be represented in int, long or long long.

50 is of type int.

unsigned literals can be specified using the u or U suffix. A decimal integer literal suffixed with u or U is of the first type where it can be represented in unsigned int, unsigned long or unsigned long long.

50U is of type unsigned int.

Why 'int' by default, but not 'byte'?

Because the Java Language Specification says so.

Section 3.10.1. Integer Literals says:

An integer literal is of type long if it is suffixed with an ASCII letter L or l (ell); otherwise it is of type int (§4.2.1).

So your numeric literal 10 is of type int.

C++ literal integer type

Yes, literal numbers have types. The type of an unsuffixed decimal integer literal is the first of int, long, long long in which the integer can be represented. The type of binary, hex and octal literals is selected similarly but with unsigned types in the list as well.

You can force the use of unsigned types by using a U suffix. If you use a single L in the suffix then the type will be at least long but it might be long long if it cannot be represented as a long. If you use LL, then the type must be long long (unless the implementation has extended types wider than long long).

The consequence is that if int is a 32-bit type and long is 64 bits, then 2147483647 has type int while 2147483648 has type long. That means that 2147483647+1 will overflow (which is undefined behaviour), while 2147483648+1 is simply 2147483649L.

This is defined by §2.3.12 ([lex.icon]) paragraph 2 of the C++ standard, and the above description is a summary of Table 7 from that section.

It's important to remember that the type of the destination of the assignment does not influence in any way the value of the expression on the right-hand side of the assignment. If you want to force a computation to have a long long result you need to force some argument of the computation to be long long; just assigning to a long long variable isn't enough:

long long a = 2147483647 + 1LL;
std::cout << a << '\n';

produces

2147483648

(live on coliru)

what are default integer values?

The type of integer literals given in base 10 is the first type in the following list in which their value can fit:

  • int
  • long int
  • long long int

For octal and hexadecimal literals, unsigned types will be considered as well, in the following order:

  • int
  • unsigned int
  • long int
  • unsigned long int
  • long long int
  • unsigned long long int

You can specify a u suffix to force unsigned types, an l suffix to force long or long long, or an ll suffix to force long long.

Reference: C99, 6.4.4.1p5



Related Topics



Leave a reply



Submit