Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/integer literal"

From cppreference.com
< cpp‎ | language
(literals were literally-insensitive, not just case-insensitive)
m (fmt)
 
(35 intermediate revisions by 7 users not shown)
Line 1: Line 1:
{{title|integer literal}}
+
{{title|Integer literal}}
 
{{cpp/language/expressions/navbar}}
 
{{cpp/language/expressions/navbar}}
 
Allows values of integer type to be used in expressions directly.
 
Allows values of integer type to be used in expressions directly.
 +
 
===Syntax===
 
===Syntax===
An integer literal is a {{rlp|expressions#Primary_expressions|primary expression}} of the form
+
An integer literal has the form
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc | num = 1 | {{spar|decimal-literal}} {{spar|integer-suffix}}{{mark optional}} }}
+
{{sdsc|num=1|{{spar|decimal-literal}} {{spar optional|integer-suffix}}}}
{{sdsc | num = 2 | {{spar|octal-literal}} {{spar|integer-suffix}}{{mark optional}} }}
+
{{sdsc|num=2|{{spar|octal-literal}} {{spar optional|integer-suffix}}}}
{{sdsc | num = 3 | {{spar|hex-literal}} {{spar|integer-suffix}}{{mark optional}} }}
+
{{sdsc|num=3|{{spar|hex-literal}} {{spar optional|integer-suffix}}}}
{{sdsc | num = 4 | notes={{mark since c++14}} | {{spar|binary-literal}} {{spar|integer-suffix}}{{mark optional}} }}
+
{{sdsc|num=4|notes={{mark since c++14}}|{{spar|binary-literal}} {{spar optional|integer-suffix}}}}
 
{{sdsc end}}
 
{{sdsc end}}
 
where
 
where
Line 17: Line 18:
 
* {{spar|integer-suffix}}, if provided, may contain one or both of the following (if both are provided, they may appear in any order:
 
* {{spar|integer-suffix}}, if provided, may contain one or both of the following (if both are provided, they may appear in any order:
 
:* {{spar|unsigned-suffix}} (the character {{tt|u}} or the character {{tt|U}})
 
:* {{spar|unsigned-suffix}} (the character {{tt|u}} or the character {{tt|U}})
:* {{spar|long-suffix}} (the character {{tt|l}} or the character {{tt|L}}){{rev inl|since=c++11| or the {{spar|long-long-suffix}} (the character sequence {{tt|ll}} or the character sequence {{tt|LL}})}}
+
:* one of
{{rev begin}}
+
::* {{spar|long-suffix}} (the character {{tt|l}} or the character {{tt|L}})
{{rev | since = c++14 |Optional single quotes({{tt|'}}) may be inserted between the digits as a separator. They are ignored by the compiler.}}
+
{{rrev|since=c++11|
{{rev end}}
+
::* {{spar|long-long-suffix}} (the character sequence {{tt|ll}} or the character sequence {{tt|LL}})
 +
}}
 +
{{rrev|since=c++23|
 +
::* {{spar|size-suffix}} (the character {{tt|z}} or the character {{tt|Z}})
 +
}}
 +
{{anchor|Single quote}}
 +
{{rrev|since=c++14|
 +
Optional single quotes ({{c/core|'}}) may be inserted between the digits as a separator; they are ignored when determining the value of the literal.
 +
}}
 +
An integer literal (as any literal) is a {{rlp|expressions#Primary expressions|primary expression}}.
 +
 
 
===Explanation===
 
===Explanation===
@1@ Decimal integer literal (base 10, the first digit is the most significant)
+
@1@ Decimal integer literal (base 10).
@2@ Octal integer literal (base 8, the first digit is the most significant)
+
@2@ Octal integer literal (base 8).
@3@ Hexadecimal integer literal (base 16, the first digit is the most significant, the letters 'a' through 'f' represent values (decimal) 10 through 15)
+
@3@ Hexadecimal integer literal (base 16, the letters {{c/core|'a'}} through {{c/core|'f'}} represent values (decimal) 10 through 15).
@4@ Binary integer literal (base 2, the first digit is the most significant)
+
@4@ Binary integer literal (base 2).
 +
 
 +
The first digit of an integer literal is the most significant.
  
The following variables are initialized to the same value:
+
Example. The following variables are initialized to the same value:
 
{{source|1=
 
{{source|1=
 
int d = 42;
 
int d = 42;
Line 36: Line 49:
 
}}
 
}}
  
The following variables are also initialized to the same value:
+
Example. The following variables are also initialized to the same value:
 
{{source|1=
 
{{source|1=
unsigned long long l1 = 18446744073709550592ull; // C++11
+
unsigned long long l1 = 18446744073709550592ull;       // C++11
 
unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14
 
unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14
unsigned long long l3 = 1844'6744'0737'0955'0592uLL; // C++14
+
unsigned long long l3 = 1844'6744'0737'0955'0592uLL;   // C++14
unsigned long long l4 = 184467'440737'0'95505'92LLU; // C++14
+
unsigned long long l4 = 184467'440737'0'95505'92LLU;   // C++14
 
}}
 
}}
  
 
===The type of the literal===
 
===The type of the literal===
The type of the integer literal is the first type in which the value can fit, from the list of types which depends on which numeric base and which {{spar|integer-suffix}} was used.
+
The type of the integer literal is the first type in which the value can fit, from the list of types which depends on which numeric base and which {{spar|integer-suffix}} was used:
  
{| class="wikitable"
+
{|class="wikitable"
|- style="text-align:center"
+
|-style="text-align:center"
! colspan="3" | Types allowed for integer literals
+
!Suffix
|- style="text-align:center"
+
!Decimal bases
| suffix
+
!Binary, octal, or hexadecimal bases
| decimal bases
+
|-style="text-align:left"
| binary, octal, or hexadecimal bases
+
|(no suffix)
|- style="text-align:left"
+
|
| no suffix
+
* {{c/core|int}}
| {{c|int}}
+
* {{c/core|long int}}
{{c|long int}}<br>
+
* {{c/core|long long int}} {{mark since c++11}}
{{c|long long int}}{{mark since c++11}}
+
|
| {{c|int}}
+
* {{c/core|int}}
{{c|unsigned int}}<br>
+
* {{c/core|unsigned int}}
{{c|long int}}<br>
+
* {{c/core|long int}}
{{c|unsigned long int}}<br>
+
* {{c/core|unsigned long int}}
{{c|long long int}}{{mark since c++11}}<br>
+
* {{c/core|long long int}} {{mark since c++11}}
{{c|unsigned long long int}}{{mark since c++11}}
+
* {{c/core|unsigned long long int}} {{mark since c++11}}
 
|-
 
|-
| {{tt|u}} or {{tt|U}}
+
|{{tt|u}} or {{tt|U}}
| {{c|unsigned int}}
+
|
{{c|unsigned long int}}<br>
+
* {{c/core|unsigned int}}
{{c|unsigned long long int}}{{mark since c++11}}
+
* {{c/core|unsigned long int}}
| {{c|unsigned int}}
+
* {{c/core|unsigned long long int}} {{mark since c++11}}
{{c|unsigned long int}}<br>
+
|
{{c|unsigned long long int}}{{mark since c++11}}
+
* {{c/core|unsigned int}}
 +
* {{c/core|unsigned long int}}
 +
* {{c/core|unsigned long long int}} {{mark since c++11}}
 
|-
 
|-
| {{tt|l}} or {{tt|L}}
+
|{{tt|l}} or {{tt|L}}
| {{c|long int}}
+
|
{{c|unsigned long int}}{{mark until c++11}}<br>
+
* {{c/core|long int}}
{{c|long long int}}{{mark since c++11}}
+
* {{c/core|unsigned long int}} {{mark until c++11}}
| {{c|long int}}
+
* {{c/core|long long int}} {{mark since c++11}}
{{c|unsigned long int}}<br>
+
|
{{c|long long int}}{{mark since c++11}}<br>
+
* {{c/core|long int}}
{{c|unsigned long long int}}{{mark since c++11}}
+
* {{c/core|unsigned long int}}
 +
* {{c/core|long long int}} {{mark since c++11}}
 +
* {{c/core|unsigned long long int}} {{mark since c++11}}
 
|-
 
|-
| both {{tt|l}}/{{tt|L}} and {{tt|u}}/{{tt|U}}
+
|both {{tt|l}}/{{tt|L}}<br>and {{tt|u}}/{{tt|U}}
| {{c|unsigned long int}}
+
|
{{c|unsigned long long int}}{{mark since c++11}}
+
* {{c/core|unsigned long int}}
| {{c|unsigned long int}}{{mark since c++11}}
+
* {{c/core|unsigned long long int}} {{mark since c++11}}
{{c|unsigned long long int}}{{mark since c++11}}
+
|
 +
* {{c/core|unsigned long int}}
 +
* {{c/core|unsigned long long int}} {{mark since c++11}}
 
|-
 
|-
| {{tt|ll}} or {{tt|LL}}
+
|{{tt|ll}} or {{tt|LL}}
| {{c|long long int}}{{mark since c++11}}
+
|
| {{c|long long int}}{{mark since c++11}}
+
* {{c/core|long long int}} {{mark since c++11}}
{{c|unsigned long long int}}{{mark since c++11}}
+
|
 +
* {{c/core|long long int}} {{mark since c++11}}
 +
* {{c/core|unsigned long long int}} {{mark since c++11}}
 
|-
 
|-
| both {{tt|ll}}/{{tt|LL}} and {{tt|u}}/{{tt|U}}
+
|both {{tt|ll}}/{{tt|LL}}<br>and {{tt|u}}/{{tt|U}}
| {{c|unsigned long long int}}{{mark since c++11}}
+
|
| {{c|unsigned long long int}}{{mark since c++11}}
+
* {{c/core|unsigned long long int}} {{mark since c++11}}
 +
|
 +
* {{c/core|unsigned long long int}} {{mark since c++11}}
 +
|-
 +
|{{tt|z}} or {{tt|Z}}
 +
|
 +
* the signed version of {{lc|std::size_t}} {{mark since c++23}}
 +
|
 +
* the signed version of {{lc|std::size_t}} {{mark since c++23}}
 +
* {{lc|std::size_t}} {{mark since c++23}}
 +
|-
 +
|both {{tt|z}}/{{tt|Z}}<br>and {{tt|u}}/{{tt|U}}
 +
|
 +
* {{lc|std::size_t}} {{mark since c++23}}
 +
|
 +
* {{lc|std::size_t}} {{mark since c++23}}
 
|}
 
|}
  
If the value of the integer literal is too big to fit in any of the types allowed by suffix/base combination and the compiler supports extended integer types (such as {{c|__int128}}) the literal may be given the extended integer type -- otherwise the program is ill-formed.
+
If the value of the integer literal {{rev inl|since=c++23|that does not have {{spar|size-suffix}}}} is too big to fit in any of the types allowed by suffix/base combination and the compiler supports an extended integer type (such as {{c|__int128}}) which can represent the value of the literal, the literal may be given that extended integer type otherwise the program is ill-formed.
  
 
===Notes===
 
===Notes===
Letters in the integer literals are case-insensitive: {{tt|0xDeAdBeEfU}} and {{tt|0XdeadBEEFu}} represent the same number (one exception is the {{spar|long-long-suffix}}, which is either {{tt|ll}} or {{tt|LL}}, never {{tt|lL}} or {{tt|Ll}})
+
Letters in the integer literals are case-insensitive: {{tt|0xDeAdBeEfU}} and {{tt|0XdeadBEEFu}} represent the same number {{rev inl|since=c++11|(one exception is the {{spar|long-long-suffix}}, which is either {{tt|ll}} or {{tt|LL}}, never {{tt|lL}} or {{tt|Ll}})}}.
  
 
There are no negative integer literals. Expressions such as {{c|-1}} apply the {{rlp|operator_arithmetic|unary minus operator}} to the value represented by the literal, which may involve implicit type conversions.
 
There are no negative integer literals. Expressions such as {{c|-1}} apply the {{rlp|operator_arithmetic|unary minus operator}} to the value represented by the literal, which may involve implicit type conversions.
  
In C prior to C99 (but not in C++), unsuffixed decimal values that do not fit in {{c|long int}} are allowed to have the type {{c|unsigned long int}}.
+
In C prior to C99 (but not in C++), unsuffixed decimal values that do not fit in {{c/core|long int}} are allowed to have the type {{c/core|unsigned long int}}.
  
When used in a controlling expression of [[cpp/preprocessor/conditional|#if]] or [[c/preprocessor/conditional|#elif]], all signed integer constants act as if they have type {{lc|std::intmax_t}} and all unsigned integer constants act as if they have type {{lc|std::uintmax_t}}.
+
{{rrev|since=c++11|
 +
When used in a controlling expression of {{ltt|cpp/preprocessor/conditional|#if}} or {{ltt|cpp/preprocessor/conditional|#elif}}, all signed integer constants act as if they have type {{lc|std::intmax_t}} and all unsigned integer constants act as if they have type {{lc|std::uintmax_t}}.
 +
}}
 +
 
 +
Due to {{rlp|translation_phases#maximal munch|maximal munch}}, hexadecimal integer literals ending in {{ttb|e}} and {{ttb|E}}, when followed by the operators {{ttb|+}} or {{ttb|-}}, must be separated from the operator with whitespace or parentheses in the source:
 +
 
 +
{{source|1=
 +
auto x = 0xE+2.0;  // error
 +
auto y = 0xa+2.0;  // OK
 +
auto z = 0xE +2.0;  // OK
 +
auto q = (0xE)+2.0; // OK
 +
}}
 +
 
 +
Otherwise, a single invalid preprocessing number token is formed, which causes further analysis to fail.
 +
 
 +
{{ftm begin|std=1|comment=1}}
 +
{{ftm|value=201304L|std=C++14|__cpp_binary_literals|[[#Syntax|Binary literals]]}}
 +
{{ftm|value=202011L|std=C++23|__cpp_size_t_suffix|Literal suffixes for {{lc|std::size_t}} and its signed version}}
 +
{{ftm end}}
  
 
===Example===
 
===Example===
 
{{example|code=
 
{{example|code=
 +
#include <cstddef>
 
#include <iostream>
 
#include <iostream>
 +
#include <type_traits>
  
 
int main()
 
int main()
 
{
 
{
std::cout << 123   << '\n'
+
    std::cout << 123 << '\n'
          << 0123   << '\n'
+
              << 0123 << '\n'
          << 0x123 << '\n'
+
              << 0x123 << '\n'
          << 0b10   << '\n'
+
              << 0b10 << '\n'
          << 12345678901234567890ull << '\n'
+
              << 12345678901234567890ull << '\n'
          << 12345678901234567890u   << '\n'; // the type is unsigned long long even
+
              << 12345678901234567890u << '\n'; // the type is unsigned long long
                                              // without a long long suffix
+
                                                // even without a long long suffix
  
//   std::cout << -9223372036854775808 << '\n'; // error: the value
+
// std::cout << -9223372036854775808 << '\n'; // error: the value
                // 9223372036854775808 cannot fit in signed long long, which is the
+
              // 9223372036854775808 cannot fit in signed long long, which is the
                // biggest type allowed for unsuffixed decimal integer literal
+
              // biggest type allowed for unsuffixed decimal integer literal
    std::cout << -9223372036854775808u << '\n'; // unary minus applied to unsigned
+
    std::cout << -9223372036854775808u << '\n'; // unary minus applied to unsigned
                // value subtracts it from 2^64, this gives 9223372036854775808
+
              // value subtracts it from 2^64, this gives 9223372036854775808
    std::cout << -9223372036854775807 - 1 << '\n'; // correct way to calculate
+
    std::cout << -9223372036854775807 - 1 << '\n'; // correct way to calculate
                                                    // the value -9223372036854775808
+
                                                  // the value -9223372036854775808
 +
 
 +
#if __cpp_size_t_suffix >= 202011L // C++23
 +
    static_assert(std::is_same_v<decltype(0UZ), std::size_t>);
 +
    static_assert(std::is_same_v<decltype(0Z), std::make_signed_t<std::size_t>>);
 +
#endif
 
}
 
}
 
|output=
 
|output=
Line 142: Line 203:
 
-9223372036854775808
 
-9223372036854775808
 
}}
 
}}
 +
 +
===Defect reports===
 +
{{dr list begin}}
 +
{{dr list item|wg=cwg|dr=2698|std=C++23|before=an integer literal with {{spar|size-suffix}} could have an extended integer type|after=ill-formed if too large}}
 +
{{dr list end}}
 +
 +
===References===
 +
{{ref std c++23}}
 +
{{ref std|section=5.13.2|title=Integer literals|id=lex.icon}}
 +
<!--{{ref std|section = 7.5.1|title= Literals|id =expr.prim.literal}}
 +
This is the source for the claim "An integer literal (as any literal) is a primary expression. "
 +
It could be added here, but it should probably be added to the expressions page instead-->
 +
{{ref std end}}
 +
{{ref std c++20}}
 +
{{ref std|section=5.13.2|title=Integer literals|id=lex.icon}}
 +
{{ref std end}}
 +
{{ref std c++17}}
 +
{{ref std|section=5.13.2|title=Integer literals|id=lex.icon}}
 +
{{ref std end}}
 +
{{ref std c++14}}
 +
{{ref std|section=2.14.2|title=Integer literals|id=lex.icon}}
 +
{{ref std end}}
 +
{{ref std c++11}}
 +
{{ref std|section=2.14.2|title=Integer literals|id=lex.icon}}
 +
{{ref std end}}
 +
<!--{{ref std c++03}}
 +
{{ref std|section=2.13.1|title=Integer literals|id=lex.icon}}
 +
{{ref std end}}-->
 +
{{ref std c++98}}
 +
{{ref std|section=2.13.1|title=Integer literals|id=lex.icon}}
 +
{{ref std end}}
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc see c | c/language/integer_constant | integer constant}}
+
{{dsc inc|cpp/language/dsc user literal}}
 +
{{dsc see c|c/language/integer constant|integer constant|nomono=true}}
 
{{dsc end}}
 
{{dsc end}}
  
[[de:cpp/language/integer literal]]
+
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}
[[es:cpp/language/integer literal]]
+
[[fr:cpp/language/integer literal]]
+
[[it:cpp/language/integer literal]]
+
[[ja:cpp/language/integer literal]]
+
[[pt:cpp/language/integer literal]]
+
[[ru:cpp/language/integer literal]]
+
[[zh:cpp/language/integer literal]]
+

Latest revision as of 10:45, 3 March 2024

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Allows values of integer type to be used in expressions directly.

Contents

[edit] Syntax

An integer literal has the form

decimal-literal integer-suffix (optional) (1)
octal-literal integer-suffix (optional) (2)
hex-literal integer-suffix (optional) (3)
binary-literal integer-suffix (optional) (4) (since C++14)

where

  • decimal-literal is a non-zero decimal digit (1, 2, 3, 4, 5, 6, 7, 8, 9), followed by zero or more decimal digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
  • octal-literal is the digit zero (0) followed by zero or more octal digits (0, 1, 2, 3, 4, 5, 6, 7)
  • hex-literal is the character sequence 0x or the character sequence 0X followed by one or more hexadecimal digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, A, b, B, c, C, d, D, e, E, f, F)
  • binary-literal is the character sequence 0b or the character sequence 0B followed by one or more binary digits (0, 1)
  • integer-suffix, if provided, may contain one or both of the following (if both are provided, they may appear in any order:
  • unsigned-suffix (the character u or the character U)
  • one of
  • long-suffix (the character l or the character L)
  • long-long-suffix (the character sequence ll or the character sequence LL)
(since C++11)
  • size-suffix (the character z or the character Z)
(since C++23)

Optional single quotes (') may be inserted between the digits as a separator; they are ignored when determining the value of the literal.

(since C++14)

An integer literal (as any literal) is a primary expression.

[edit] Explanation

1) Decimal integer literal (base 10).
2) Octal integer literal (base 8).
3) Hexadecimal integer literal (base 16, the letters 'a' through 'f' represent values (decimal) 10 through 15).
4) Binary integer literal (base 2).

The first digit of an integer literal is the most significant.

Example. The following variables are initialized to the same value:

int d = 42;
int o = 052;
int x = 0x2a;
int X = 0X2A;
int b = 0b101010; // C++14

Example. The following variables are also initialized to the same value:

unsigned long long l1 = 18446744073709550592ull;       // C++11
unsigned long long l2 = 18'446'744'073'709'550'592llu; // C++14
unsigned long long l3 = 1844'6744'0737'0955'0592uLL;   // C++14
unsigned long long l4 = 184467'440737'0'95505'92LLU;   // C++14

[edit] The type of the literal

The type of the integer literal is the first type in which the value can fit, from the list of types which depends on which numeric base and which integer-suffix was used:

Suffix Decimal bases Binary, octal, or hexadecimal bases
(no suffix)
  • int
  • long int
  • long long int (since C++11)
  • int
  • unsigned int
  • long int
  • unsigned long int
  • long long int (since C++11)
  • unsigned long long int (since C++11)
u or U
  • unsigned int
  • unsigned long int
  • unsigned long long int (since C++11)
  • unsigned int
  • unsigned long int
  • unsigned long long int (since C++11)
l or L
  • long int
  • unsigned long int (until C++11)
  • long long int (since C++11)
  • long int
  • unsigned long int
  • long long int (since C++11)
  • unsigned long long int (since C++11)
both l/L
and u/U
  • unsigned long int
  • unsigned long long int (since C++11)
  • unsigned long int
  • unsigned long long int (since C++11)
ll or LL
  • long long int (since C++11)
  • long long int (since C++11)
  • unsigned long long int (since C++11)
both ll/LL
and u/U
  • unsigned long long int (since C++11)
  • unsigned long long int (since C++11)
z or Z
both z/Z
and u/U

If the value of the integer literal that does not have size-suffix(since C++23) is too big to fit in any of the types allowed by suffix/base combination and the compiler supports an extended integer type (such as __int128) which can represent the value of the literal, the literal may be given that extended integer type — otherwise the program is ill-formed.

[edit] Notes

Letters in the integer literals are case-insensitive: 0xDeAdBeEfU and 0XdeadBEEFu represent the same number (one exception is the long-long-suffix, which is either ll or LL, never lL or Ll)(since C++11).

There are no negative integer literals. Expressions such as -1 apply the unary minus operator to the value represented by the literal, which may involve implicit type conversions.

In C prior to C99 (but not in C++), unsuffixed decimal values that do not fit in long int are allowed to have the type unsigned long int.

When used in a controlling expression of #if or #elif, all signed integer constants act as if they have type std::intmax_t and all unsigned integer constants act as if they have type std::uintmax_t.

(since C++11)

Due to maximal munch, hexadecimal integer literals ending in e and E, when followed by the operators + or -, must be separated from the operator with whitespace or parentheses in the source:

auto x = 0xE+2.0;   // error
auto y = 0xa+2.0;   // OK
auto z = 0xE +2.0;  // OK
auto q = (0xE)+2.0; // OK

Otherwise, a single invalid preprocessing number token is formed, which causes further analysis to fail.

Feature-test macro Value Std Feature
__cpp_binary_literals 201304L (C++14) Binary literals
__cpp_size_t_suffix 202011L (C++23) Literal suffixes for std::size_t and its signed version

[edit] Example

#include <cstddef>
#include <iostream>
#include <type_traits>
 
int main()
{
    std::cout << 123 << '\n'
              << 0123 << '\n'
              << 0x123 << '\n'
              << 0b10 << '\n'
              << 12345678901234567890ull << '\n'
              << 12345678901234567890u << '\n'; // the type is unsigned long long
                                                // even without a long long suffix
 
//  std::cout << -9223372036854775808 << '\n'; // error: the value
               // 9223372036854775808 cannot fit in signed long long, which is the
               // biggest type allowed for unsuffixed decimal integer literal
    std::cout << -9223372036854775808u << '\n'; // unary minus applied to unsigned
               // value subtracts it from 2^64, this gives 9223372036854775808
    std::cout << -9223372036854775807 - 1 << '\n'; // correct way to calculate
                                                   // the value -9223372036854775808
 
#if __cpp_size_t_suffix >= 202011L // C++23
    static_assert(std::is_same_v<decltype(0UZ), std::size_t>);
    static_assert(std::is_same_v<decltype(0Z), std::make_signed_t<std::size_t>>);
#endif
}

Output:

123
83
291
2
12345678901234567890
12345678901234567890
9223372036854775808
-9223372036854775808

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
CWG 2698 C++23 an integer literal with size-suffix could have an extended integer type ill-formed if too large

[edit] References

  • C++23 standard (ISO/IEC 14882:2024):
  • 5.13.2 Integer literals [lex.icon]
  • C++20 standard (ISO/IEC 14882:2020):
  • 5.13.2 Integer literals [lex.icon]
  • C++17 standard (ISO/IEC 14882:2017):
  • 5.13.2 Integer literals [lex.icon]
  • C++14 standard (ISO/IEC 14882:2014):
  • 2.14.2 Integer literals [lex.icon]
  • C++11 standard (ISO/IEC 14882:2011):
  • 2.14.2 Integer literals [lex.icon]
  • C++98 standard (ISO/IEC 14882:1998):
  • 2.13.1 Integer literals [lex.icon]

[edit] See also

user-defined literals(C++11) literals with user-defined suffix[edit]
C documentation for integer constant