C++ Module 19 – C++ for DSA and competitive programming
Online judge C++ compilers, flags and limits
The compilers, language modes and flags that Codeforces, AtCoder, LeetCode and the ICPC use for C++, what they change, and how to copy them locally.
What you will learn
- Find the compiler, standard library, language mode and flags a judge uses for C++
- Avoid library features and types that a judge's environment does not support
- Reproduce a judge's build on your own computer with its documented flags
Before you start
What you’ll learn · Before you start
What you will learn
- Find the compiler, standard library, language mode and flags a judge uses for C++
- Avoid library features and types that a judge's environment does not support
- Reproduce a judge's build on your own computer with its documented flags
Before you start
On this page
An online judge does not build your program the way your computer does. It compiles the file with its own compiler, standard library, language mode and flags, on its own operating system, and then runs it under limits of its own. Four judges show how far apart those can be: Codeforces builds its “GNU G++23 14.2” entry with a Windows build of GCC 14.2, AtCoder builds “C++23 (GCC 15.2.0)” for x86-64 Linux, LeetCode compiles with Clang 19 and the standard library of GCC 14 with AddressSanitizer switched on, and the ICPC World Finals use GCC 13.2 in C++20 mode. One file can compile on one of them and fail on another, or print a different answer. Four layers explain almost every such case: the language mode, the library version, the platform’s type sizes and the flags. Each one is shown below with real builds on Apple clang 21 and GCC 16, followed by a probe you can submit to any judge and the commands that copy each judge’s build on your computer.
The four judges at a glance
Each judge publishes its environment: Codeforces keeps a list of its command lines, AtCoder publishes a language list with each language update, LeetCode has a help-centre article, and the ICPC publishes the environment of each World Finals. This is what those pages say for C++:
- Codeforces, “GNU G++23 14.2 (64 bit, msys 2)”: GCC 14.2 with libstdc++ in
-std=c++23mode, on 64-bit Windows, with-O2,-DONLINE_JUDGE,-staticand a 256 MiB stack. - AtCoder, “C++23 (GCC 15.2.0)”: GCC 15.2 with libstdc++, AC Library 1.6 and Boost 1.88, in
-std=gnu++23mode on x86-64 Linux, with-O2,-march=native,-DONLINE_JUDGE,-DATCODERand-ftrivial-auto-var-init=zero. - LeetCode, C++: Clang 19 with libstdc++ from GCC 14 in C++23 mode, with
-O2and AddressSanitizer. Most headers are included for you, and the platform is not stated. - ICPC World Finals: GCC 13.2.0 with libstdc++ in
-std=gnu++20mode, on 64-bit Ubuntu 24.04, with-O2,-gand-static.
The judges offer more than one C++ entry, and the one you pick matters as much as the judge. Codeforces still lists “GNU G++17 7.3.0” and “GNU G++14 6.4.0”, both 32-bit, and “GNU G++20 11.2.0 (64 bit, winlibs)”. AtCoder also has “C++23 (Clang 21.1.0)”, built with libc++ instead of libstdc++. Judges also update their compilers from time to time, so read the judge’s own page again before a contest.
The four layers where a judge's build can differ from the one on your computer
Text description of the diagram
The diagram is a column of six boxes joined by arrows, read from top to bottom.
- solution.cpp, your source file.
- Language mode: -std=c++23 on Codeforces, gnu++23 on AtCoder, gnu++20 at the ICPC World Finals.
- Standard library: libstdc++ from GCC 14 on Codeforces and LeetCode, from GCC 15 on AtCoder and from GCC 13 at the World Finals, or libc++ with Clang.
- Platform: on Windows, where Codeforces judges, long is 4 bytes; on Linux it is 8 bytes.
- Flags: -O2 everywhere, AddressSanitizer on LeetCode, -DONLINE_JUDGE on Codeforces and AtCoder, locals set to zero on AtCoder, and a 256 MiB stack on Codeforces.
- Verdict: what the judge reports.
A difference at any layer can change whether the file compiles, what it prints, or how long it runs.
Language mode and library version
The -std= flag picks the language, but the library decides which library features exist, and libstdc++ offers its
C++23 features only in a C++23 mode. This solution uses two of them, std::println and std::views::enumerate:
// modern.cpp: prints the total of n numbers, then the position and value of each number above their average.
#include <cstdio>
#include <print>
#include <ranges>
#include <vector>
int main() {
int n = 0;
if (std::scanf("%d", &n) != 1) return 1;
std::vector<long> a(n);
for (long& x : a)
if (std::scanf("%ld", &x) != 1) return 1;
long total = 0;
for (long x : a) total += x;
std::println("total {}", total);
for (auto [i, x] : std::views::enumerate(a))
if (x * n > total) std::println("{} {}", i + 1, x);
} The session builds it with each judge’s documented flags, as far as a Mac allows: -static and the Windows stack
option are left out, because the macOS linker rejects them.
from session import run
# One solution built with each judge's documented flags, as far as a Mac allows: macOS cannot link with -static, and
# -Wl,--stack= is an option of the Windows linker, so those two are left out. Compile errors are cut to their
# "error:" lines.
run("""
# Codeforces, GNU G++23 14.2 (64 bit, msys 2)
g++-16 -Wall -Wextra -Wconversion -DONLINE_JUDGE -O2 -std=c++23 modern.cpp -o cf && ./cf < numbers.txt
# AtCoder, C++23 (GCC 15.2.0): the flags that change what the program does
g++-16 -DATCODER -DONLINE_JUDGE -O2 -Wall -Wextra -ftrivial-auto-var-init=zero -std=gnu++23 modern.cpp -o ac && ./ac < numbers.txt
# ICPC World Finals: GCC in gnu++20 mode
g++-16 -x c++ -g -O2 -std=gnu++20 modern.cpp -o icpc 2>&1 | grep error:
# Apple clang 21 with its own libc++
clang++ -std=c++23 -O2 -Wall -Wextra modern.cpp -o mac 2>&1 | grep error:
""") Output
# Codeforces, GNU G++23 14.2 (64 bit, msys 2) $ g++-16 -Wall -Wextra -Wconversion -DONLINE_JUDGE -O2 -std=c++23 modern.cpp -o cf && ./cf < numbers.txt total 5200000000 2 2000000000 3 1500000000 # AtCoder, C++23 (GCC 15.2.0): the flags that change what the program does $ g++-16 -DATCODER -DONLINE_JUDGE -O2 -Wall -Wextra -ftrivial-auto-var-init=zero -std=gnu++23 modern.cpp -o ac && ./ac < numbers.txt total 5200000000 2 2000000000 3 1500000000 # ICPC World Finals: GCC in gnu++20 mode $ g++-16 -x c++ -g -O2 -std=gnu++20 modern.cpp -o icpc 2>&1 | grep error: modern.cpp:15:10: error: 'println' is not a member of 'std' modern.cpp:16:36: error: 'enumerate' is not a member of 'std::views' modern.cpp:17:33: error: 'println' is not a member of 'std' # Apple clang 21 with its own libc++ $ clang++ -std=c++23 -O2 -Wall -Wextra modern.cpp -o mac 2>&1 | grep error: modern.cpp:16:36: error: no member named 'enumerate' in namespace 'std::ranges::views'
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 judges_session.py
GCC 16 with Codeforces’ and AtCoder’s flags compiled it and printed the total and the two numbers above the average.
In the gnu++20 mode of the World Finals the same compiler stopped with 'println' is not a member of 'std' and
'enumerate' is not a member of 'std::views': the library has both, but hides them in C++20 mode. The GCC 13.2 of
the World Finals could not offer std::println in any mode, because libstdc++ added std::print in GCC 14.1. Apple
clang 21 failed for a different reason: its libc++ 22 has no views::enumerate, which libc++’s status page lists as
new in version 23.
The fix is to write for the oldest environment you submit to. This version uses nothing newer than C++20 and a
64-bit long long total:
// portable.cpp: the same program with nothing newer than C++20 and a total of 64 bits on every platform.
#include <cstdio>
#include <vector>
int main() {
int n = 0;
if (std::scanf("%d", &n) != 1) return 1;
std::vector<long long> a(n);
for (long long& x : a)
if (std::scanf("%lld", &x) != 1) return 1;
long long total = 0;
for (long long x : a) total += x;
std::printf("total %lld\n", total);
for (int i = 0; i < n; ++i)
if (a[i] * n > total) std::printf("%d %lld\n", i + 1, a[i]);
} from session import run
# portable.cpp with the same four sets of flags: each build compiles and prints the same three lines.
run("""
g++-16 -Wall -Wextra -Wconversion -DONLINE_JUDGE -O2 -std=c++23 portable.cpp -o cf && ./cf < numbers.txt
g++-16 -DATCODER -DONLINE_JUDGE -O2 -Wall -Wextra -ftrivial-auto-var-init=zero -std=gnu++23 portable.cpp -o ac && ./ac < numbers.txt
g++-16 -x c++ -g -O2 -std=gnu++20 portable.cpp -o icpc && ./icpc < numbers.txt
clang++ -std=c++23 -O2 -Wall -Wextra portable.cpp -o mac && ./mac < numbers.txt
""") Output
$ g++-16 -Wall -Wextra -Wconversion -DONLINE_JUDGE -O2 -std=c++23 portable.cpp -o cf && ./cf < numbers.txt total 5200000000 2 2000000000 3 1500000000 $ g++-16 -DATCODER -DONLINE_JUDGE -O2 -Wall -Wextra -ftrivial-auto-var-init=zero -std=gnu++23 portable.cpp -o ac && ./ac < numbers.txt total 5200000000 2 2000000000 3 1500000000 $ g++-16 -x c++ -g -O2 -std=gnu++20 portable.cpp -o icpc && ./icpc < numbers.txt total 5200000000 2 2000000000 3 1500000000 $ clang++ -std=c++23 -O2 -Wall -Wextra portable.cpp -o mac && ./mac < numbers.txt total 5200000000 2 2000000000 3 1500000000
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 portable_session.py
All four builds compiled it and printed the same three lines.
The platform: the size of long, and long double
The C++ standard only sets minimum widths: at least 32 bits for long and at least 64 for long long. The rest is
the platform’s choice. Clang can print the sizes it predefines for another platform without building anything for
it, and GCC for the same platform agrees, because the sizes belong to the platform’s binary interface:
from session import run
# What Clang predefines for four targets, without building anything for them: 64-bit and 32-bit Windows with the
# MinGW-w64 runtime (Codeforces' GNU compilers), x86-64 Linux (AtCoder and the ICPC World Finals) and Apple silicon.
# -E -dM prints the macros a compiler predefines; the sizes are the target's, so GCC for the same target agrees.
run("""
clang++ -target x86_64-w64-mingw32 -E -dM -x c++ /dev/null | grep -E '__SIZEOF_(LONG|LONG_DOUBLE|INT128)__ |__LDBL_MANT_DIG__ ' | sort
clang++ -target i686-w64-mingw32 -E -dM -x c++ /dev/null | grep -E '__SIZEOF_(LONG|LONG_DOUBLE|INT128)__ |__LDBL_MANT_DIG__ ' | sort
clang++ -target x86_64-pc-linux-gnu -E -dM -x c++ /dev/null | grep -E '__SIZEOF_(LONG|LONG_DOUBLE|INT128)__ |__LDBL_MANT_DIG__ ' | sort
clang++ -target arm64-apple-macos -E -dM -x c++ /dev/null | grep -E '__SIZEOF_(LONG|LONG_DOUBLE|INT128)__ |__LDBL_MANT_DIG__ ' | sort
""") Output
$ clang++ -target x86_64-w64-mingw32 -E -dM -x c++ /dev/null | grep -E '__SIZEOF_(LONG|LONG_DOUBLE|INT128)__ |__LDBL_MANT_DIG__ ' | sort #define __LDBL_MANT_DIG__ 64 #define __SIZEOF_INT128__ 16 #define __SIZEOF_LONG__ 4 #define __SIZEOF_LONG_DOUBLE__ 16 $ clang++ -target i686-w64-mingw32 -E -dM -x c++ /dev/null | grep -E '__SIZEOF_(LONG|LONG_DOUBLE|INT128)__ |__LDBL_MANT_DIG__ ' | sort #define __LDBL_MANT_DIG__ 64 #define __SIZEOF_LONG__ 4 #define __SIZEOF_LONG_DOUBLE__ 12 $ clang++ -target x86_64-pc-linux-gnu -E -dM -x c++ /dev/null | grep -E '__SIZEOF_(LONG|LONG_DOUBLE|INT128)__ |__LDBL_MANT_DIG__ ' | sort #define __LDBL_MANT_DIG__ 64 #define __SIZEOF_INT128__ 16 #define __SIZEOF_LONG__ 8 #define __SIZEOF_LONG_DOUBLE__ 16 $ clang++ -target arm64-apple-macos -E -dM -x c++ /dev/null | grep -E '__SIZEOF_(LONG|LONG_DOUBLE|INT128)__ |__LDBL_MANT_DIG__ ' | sort #define __LDBL_MANT_DIG__ 53 #define __SIZEOF_INT128__ 16 #define __SIZEOF_LONG__ 8 #define __SIZEOF_LONG_DOUBLE__ 8
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 targets_session.py
The first target, x86_64-w64-mingw32, is what Codeforces’ 64-bit GNU compilers build for, and there
__SIZEOF_LONG__ is 4: Windows keeps long at 32 bits, as Microsoft’s table of data type ranges shows for its own
compiler. On Codeforces a long holds at most 2,147,483,647, so the 5,200,000,000 total of the first session would
overflow there, while x86-64 Linux, the platform of AtCoder and the World Finals, gives long 8 bytes. Use
long long or std::int64_t for every value that can pass two billion.
The 32-bit target, which Codeforces’ G++17 7.3.0 and G++14 6.4.0 entries use, has no __SIZEOF_INT128__: GCC’s
manual offers __int128 only on targets with an integer mode wide enough for 128 bits, so a solution that multiplies
two 64-bit values in __int128 compiles only on the 64-bit entries.
The last line is a trap for anyone who practises on a Mac with Apple silicon. There long double is 8 bytes with 53
bits of precision: Apple’s ARM64 notes say it is identical to double. Every x86-64 judge above gives it 64 bits of
precision, so a geometry answer computed in long double can differ from the judge’s in its last digits, in either
direction. Print answers with the precision the problem asks for, and compare with a tolerance when you test.
Flags that change what a program does
Four of the judges’ flags change behaviour rather than speed:
-DONLINE_JUDGEis defined by Codeforces and AtCoder. The World Finals command line does not define it, so code that reads from a file unlessONLINE_JUDGEis defined tries to open that file at the contest.- AddressSanitizer at LeetCode stops a run that reads past the end of an array, which an unchecked build often
survives with a wrong number. Build with
-fsanitize=addresswhen you practise, as the sanitizers lesson shows. - A 256 MiB stack at Codeforces, set with
-Wl,--stack=268435456, lets recursion go much deeper than a default stack of a few megabytes allows. The World Finals page names no stack size for C++, so recursion that is a million calls deep needs care there; a later lesson of this module turns deep recursion into loops. -ftrivial-auto-var-init=zeroat AtCoder starts every uninitialised local variable at zero. That hides a common bug, a total that is never set to 0:
// uninit_total.cpp: adds up n numbers, but the total is never set to 0 (the bug is on line 7).
#include <cstdio>
int main() {
int n = 0;
if (std::scanf("%d", &n) != 1) return 1;
long long total; // should be: long long total = 0;
for (int i = 0; i < n; ++i) {
long long x = 0;
if (std::scanf("%lld", &x) != 1) return 1;
total += x;
}
std::printf("%lld\n", total);
} from session import run
# The same bug built three ways: as AtCoder builds it (locals start at zero), and with GCC's and Clang's "pattern",
# which fills every uninitialised local with a byte pattern instead. -Wall reports the bug in every build.
run("""
g++-16 -std=gnu++23 -O2 -Wall -Wextra -ftrivial-auto-var-init=zero uninit_total.cpp -o zero && echo 3 10 20 30 | ./zero
g++-16 -std=gnu++23 -O2 -Wall -Wextra -ftrivial-auto-var-init=pattern uninit_total.cpp -o pattern && echo 3 10 20 30 | ./pattern
clang++ -std=c++23 -O2 -Wall -Wextra -ftrivial-auto-var-init=pattern uninit_total.cpp -o pattern-clang && echo 3 10 20 30 | ./pattern-clang
""") Output
$ g++-16 -std=gnu++23 -O2 -Wall -Wextra -ftrivial-auto-var-init=zero uninit_total.cpp -o zero && echo 3 10 20 30 | ./zero
uninit_total.cpp: In function 'int main()':
uninit_total.cpp:11:15: warning: 'total' may be used uninitialized [-Wmaybe-uninitialized]
11 | total += x;
| ~~~~~~^~~~
uninit_total.cpp:7:15: note: 'total' was declared here
7 | long long total; // should be: long long total = 0;
| ^~~~~
60
$ g++-16 -std=gnu++23 -O2 -Wall -Wextra -ftrivial-auto-var-init=pattern uninit_total.cpp -o pattern && echo 3 10 20 30 | ./pattern
uninit_total.cpp: In function 'int main()':
uninit_total.cpp:11:15: warning: 'total' may be used uninitialized [-Wmaybe-uninitialized]
11 | total += x;
| ~~~~~~^~~~
uninit_total.cpp:7:15: note: 'total' was declared here
7 | long long total; // should be: long long total = 0;
| ^~~~~
-72340172838076614
$ clang++ -std=c++23 -O2 -Wall -Wextra -ftrivial-auto-var-init=pattern uninit_total.cpp -o pattern-clang && echo 3 10 20 30 | ./pattern-clang
uninit_total.cpp:11:9: warning: variable 'total' is uninitialized when used here [-Wuninitialized]
11 | total += x;
| ^~~~~
uninit_total.cpp:7:20: note: initialize the variable 'total' to silence this warning
7 | long long total; // should be: long long total = 0;
| ^
| = 0
1 warning generated.
-6148914691236517146
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 uninit_session.py
Built as AtCoder builds it, the program printed 60, the right answer. With pattern, which GCC’s manual describes as
the byte 0xFE repeated, the same file printed -72340172838076614, and Clang’s pattern of 0xAA bytes gave
-6148914691236517146: both are the pattern read as a 64-bit number, plus 60. Without either flag the value is whatever
the stack holds, so the bug may pass your tests and fail on another judge. -Wall reported it in every build, and
-ftrivial-auto-var-init=pattern is a good flag for practice builds, because it turns this bug into an answer that is
obviously wrong.
Time and memory limits
Time and memory limits belong to each problem, not to the judge, and they are part of the statement. Two details are
easy to miss. The World Finals page counts the whole process against the memory limit, runtime environment
included, so the memory the program needs before it reads any input counts as well as your arrays. And no judge here
names its processor except to promise, in the World Finals’ case, a machine at least as powerful as the teams’ own.
Time your solution with -O2 on your computer and keep a good margin below the limit, because the judge’s machine
may be slower than yours.
A probe for any judge
The surest way to learn an environment is to ask it. This program prints the language version, the compiler and library, the type sizes and a few feature-test macros. It uses nothing newer than C++20, so it compiles everywhere:
// probe.cpp: prints what a judge's compiler, library and platform give a solution.
// It needs nothing newer than C++20, so it compiles on every judge in this lesson: submit it through the judge's
// "run without judging" page and compare what it prints with your own computer.
#include <cstdio>
#include <limits>
#include <version> // the library's feature-test macros (C++20)
int main() {
std::printf("%-28s %ld\n", "__cplusplus", static_cast<long>(__cplusplus));
#if defined(__clang__)
std::printf("%-28s Clang %d.%d\n", "compiler", __clang_major__, __clang_minor__);
#elif defined(__GNUC__)
std::printf("%-28s GCC %d.%d\n", "compiler", __GNUC__, __GNUC_MINOR__);
#elif defined(_MSC_VER)
std::printf("%-28s MSVC %d\n", "compiler", _MSC_VER);
#endif
#if defined(_LIBCPP_VERSION)
std::printf("%-28s libc++ %d\n", "standard library", _LIBCPP_VERSION / 10000);
#elif defined(_GLIBCXX_RELEASE)
std::printf("%-28s libstdc++ %d\n", "standard library", _GLIBCXX_RELEASE);
#elif defined(_MSVC_STL_VERSION)
std::printf("%-28s MSVC STL %d\n", "standard library", _MSVC_STL_VERSION);
#endif
// Sizes are printed as int with %d: the old C runtime of 32-bit Windows compilers has no %zu.
std::printf("%-28s %d, %d, %d\n", "int, long, long long bytes", static_cast<int>(sizeof(int)),
static_cast<int>(sizeof(long)), static_cast<int>(sizeof(long long)));
std::printf("%-28s %d bytes, %d bits of precision\n", "long double", static_cast<int>(sizeof(long double)),
std::numeric_limits<long double>::digits);
#ifdef __SIZEOF_INT128__
std::printf("%-28s %s\n", "__int128", "yes");
#else
std::printf("%-28s %s\n", "__int128", "no");
#endif
#ifdef ONLINE_JUDGE
std::printf("%-28s %s\n", "ONLINE_JUDGE", "defined");
#else
std::printf("%-28s %s\n", "ONLINE_JUDGE", "not defined");
#endif
// Library features (from <version>) and one language feature: the value names the paper's year and month.
#ifdef __cpp_lib_format
std::printf("%-28s %ld\n", "std::format", static_cast<long>(__cpp_lib_format));
#else
std::printf("%-28s %s\n", "std::format", "no");
#endif
#ifdef __cpp_lib_print
std::printf("%-28s %ld\n", "std::print", static_cast<long>(__cpp_lib_print));
#else
std::printf("%-28s %s\n", "std::print", "no");
#endif
#ifdef __cpp_lib_ranges_to_container
std::printf("%-28s %ld\n", "std::ranges::to", static_cast<long>(__cpp_lib_ranges_to_container));
#else
std::printf("%-28s %s\n", "std::ranges::to", "no");
#endif
#ifdef __cpp_lib_ranges_zip
std::printf("%-28s %ld\n", "std::views::zip", static_cast<long>(__cpp_lib_ranges_zip));
#else
std::printf("%-28s %s\n", "std::views::zip", "no");
#endif
#ifdef __cpp_lib_ranges_enumerate
std::printf("%-28s %ld\n", "std::views::enumerate", static_cast<long>(__cpp_lib_ranges_enumerate));
#else
std::printf("%-28s %s\n", "std::views::enumerate", "no");
#endif
#ifdef __cpp_lib_flat_map
std::printf("%-28s %ld\n", "std::flat_map", static_cast<long>(__cpp_lib_flat_map));
#else
std::printf("%-28s %s\n", "std::flat_map", "no");
#endif
#ifdef __cpp_lib_format_ranges
std::printf("%-28s %ld\n", "formatting ranges", static_cast<long>(__cpp_lib_format_ranges));
#else
std::printf("%-28s %s\n", "formatting ranges", "no");
#endif
#ifdef __cpp_explicit_this_parameter
std::printf("%-28s %ld\n", "deducing this (language)", static_cast<long>(__cpp_explicit_this_parameter));
#else
std::printf("%-28s %s\n", "deducing this (language)", "no");
#endif
} from session import run
# The probe built three ways: Apple clang 21 with its libc++, GCC 16 in AtCoder's gnu++23 mode with ONLINE_JUDGE
# defined, and GCC 16 in the gnu++20 mode of the ICPC World Finals.
run("""
clang++ -std=c++23 -O2 probe.cpp -o probe && ./probe
g++-16 -std=gnu++23 -O2 -DONLINE_JUDGE probe.cpp -o probe-gnu23 && ./probe-gnu23
g++-16 -std=gnu++20 -O2 probe.cpp -o probe-gnu20 && ./probe-gnu20
""") Output
$ clang++ -std=c++23 -O2 probe.cpp -o probe && ./probe __cplusplus 202302 compiler Clang 21.0 standard library libc++ 22 int, long, long long bytes 4, 8, 8 long double 8 bytes, 53 bits of precision __int128 yes ONLINE_JUDGE not defined std::format 202110 std::print 202207 std::ranges::to 202202 std::views::zip 202110 std::views::enumerate no std::flat_map 202511 formatting ranges 202207 deducing this (language) 202110 $ g++-16 -std=gnu++23 -O2 -DONLINE_JUDGE probe.cpp -o probe-gnu23 && ./probe-gnu23 __cplusplus 202302 compiler GCC 16.2 standard library libstdc++ 16 int, long, long long bytes 4, 8, 8 long double 8 bytes, 53 bits of precision __int128 yes ONLINE_JUDGE defined std::format 202304 std::print 202406 std::ranges::to 202202 std::views::zip 202110 std::views::enumerate 202302 std::flat_map 202511 formatting ranges 202207 deducing this (language) 202110 $ g++-16 -std=gnu++20 -O2 probe.cpp -o probe-gnu20 && ./probe-gnu20 __cplusplus 202002 compiler GCC 16.2 standard library libstdc++ 16 int, long, long long bytes 4, 8, 8 long double 8 bytes, 53 bits of precision __int128 yes ONLINE_JUDGE not defined std::format 202304 std::print no std::ranges::to no std::views::zip no std::views::enumerate no std::flat_map no formatting ranges no deducing this (language) no
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 probe_session.py
On this Mac, Apple clang’s libc++ 22 reported std::print and std::flat_map but no views::enumerate, while GCC
16’s libstdc++ in gnu++23 mode reported all of them and ONLINE_JUDGE defined. In gnu++20 mode the same library
reported none of the C++23 features, only std::format, which is C++20. Both builds report 8 bytes for long double
because this machine is Apple silicon. A feature-test macro holds a year and month as one number, from the paper that
added or last changed the feature, and a missing macro means the feature is missing.
Most judges have a page that compiles and runs code without judging it: Codeforces calls it Custom Invocation and AtCoder calls it Custom Test. Run the probe there once for the entry you use, and keep its output next to your template.
Reproducing a judge on your computer
This script holds one build command per judge, as close to each judge’s build as a computer of your own allows, and its comments say what each command cannot copy:
#!/bin/sh
# judge_builds.sh: builds one solution the way each judge builds it, as far as one computer allows.
# Usage: sh judge_builds.sh solution.cpp
# On a Mac, g++ starts Apple clang: put Homebrew's GCC first in PATH under the name g++.
set -e
src=${1:-solution.cpp}
# Codeforces, GNU G++23 14.2. Not copied: the 4-byte long and the 256 MiB stack of its Windows build.
g++ -std=c++23 -O2 -Wall -Wextra -Wconversion -DONLINE_JUDGE "$src" -o codeforces
# AtCoder, C++23 (GCC 15.2.0). Add -I with the folders of AC Library and Boost if you use them.
g++ -std=gnu++23 -O2 -Wall -Wextra -DONLINE_JUDGE -DATCODER -ftrivial-auto-var-init=zero "$src" -o atcoder
# LeetCode, C++. Not copied: GCC 14's libstdc++, if your Clang uses libc++, as Apple's does.
clang++ -std=c++23 -O2 -fsanitize=address "$src" -o leetcode
# ICPC World Finals. Not copied: GCC 13's library, if your GCC is newer.
g++ -std=gnu++20 -O2 -g "$src" -o world-finals from session import run
# judge_builds.sh with Homebrew's GCC 16 under the name g++, then each of the four programs on the same input.
run("""
mkdir -p gcc-bin && ln -sf "$(command -v g++-16)" gcc-bin/g++
PATH="$PWD/gcc-bin:$PATH" g++ --version | head -n 1
PATH="$PWD/gcc-bin:$PATH" sh judge_builds.sh portable.cpp
for judge in codeforces atcoder leetcode world-finals; do echo "$judge: $(./$judge < numbers.txt | head -n 1)"; done
""") Output
$ mkdir -p gcc-bin && ln -sf "$(command -v g++-16)" gcc-bin/g++ $ PATH="$PWD/gcc-bin:$PATH" g++ --version | head -n 1 g++ (Homebrew GCC 16.2.0) 16.2.0 $ PATH="$PWD/gcc-bin:$PATH" sh judge_builds.sh portable.cpp $ for judge in codeforces atcoder leetcode world-finals; do echo "$judge: $(./$judge < numbers.txt | head -n 1)"; done codeforces: total 5200000000 atcoder: total 5200000000 leetcode: total 5200000000 world-finals: total 5200000000
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 reproduce_session.py
All four builds printed the same total. On a Mac, g++ starts Apple clang, so the session first makes a folder in
which g++ is Homebrew’s GCC 16 and puts that folder at the front of PATH; on Linux, g++ is GCC already.
Use a compiler of the same family, and of the same major version where you can: a newer GCC accepts library
features that an older judge lacks, even in the same mode. Homebrew’s gcc formula installs GCC 16 as g++-16 on a
Mac, as the installation lesson shows. A Linux container gives you the
judges’ 8-byte long, and an x86-64 Linux machine also their long double with 64 bits of precision.
Exercise: ten features, four judges
For each feature below, decide whether a solution that uses it compiles and works on each of the four judges described at the top: Codeforces’ G++23 14.2, AtCoder’s GCC 15.2, LeetCode and the World Finals. Use that list, the probe’s output and the status pages of libstdc++, libc++, GCC and Clang listed under References.
std::printlnstd::formatstd::views::enumeratestd::ranges::tostd::flat_map- Printing a whole vector with
std::println - Deducing
this, for example in a recursive lambda #include <bits/stdc++.h>- A
longthat holds 3,000,000,000 std::mdspan
Hint: find the GCC version that added each library feature, then ask whether the judge’s mode is C++23.
One solution
std::println: Codeforces, AtCoder and LeetCode, but not the World Finals.std::format: all four.std::views::enumerate: Codeforces, AtCoder and LeetCode, but not the World Finals.std::ranges::to: Codeforces, AtCoder and LeetCode, but not the World Finals.std::flat_map: AtCoder only.- Printing a whole vector with
std::println: AtCoder only. - Deducing
this: Codeforces, AtCoder and LeetCode, but not the World Finals. #include <bits/stdc++.h>: all four.- A
longthat holds 3,000,000,000: AtCoder and the World Finals, but not Codeforces; LeetCode does not say. std::mdspan: none of the four.
libstdc++‘s status page gives the versions: std::format, views::zip and views::enumerate arrived in GCC 13.1,
std::print and ranges::to in 14.1, std::flat_map and the formatting of whole ranges in 15.1, and std::mdspan
only in 16.1, newer than every judge here. LeetCode pairs Clang with GCC 14’s library, so its library features are GCC
14’s. The World Finals combine GCC 13.2 with gnu++20 mode, which rules out every C++23 feature; std::format is C++20
and works. Deducing this is a language feature, added in GCC 14 and Clang 18, so the World Finals’ GCC 13.2 rejects
it in any mode. bits/stdc++.h is a header of libstdc++, which all four judges use, but Apple clang’s libc++ has no
such file. LeetCode’s page does not name its platform, so assume nothing about long there and use long long.
Check yourself
6 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.
Interview questions
Why can a solution that keeps 64-bit sums in long be accepted on AtCoder and fail on Codeforces? (warm-up)
Because the size of long belongs to the platform, not to C++. The standard only promises at least 32 bits. AtCoder
judges on x86-64 Linux, where long has 64 bits, so a sum such as 5,200,000,000 fits. Codeforces’ GNU compilers
build for Windows, which keeps long at 32 bits, so the same sum passes 2,147,483,647 and overflows: signed overflow
is undefined behaviour, and in practice the total wraps to a wrong value. Use long long or std::int64_t, which
have at least 64 bits everywhere. Clang’s predefined macros show the difference directly: __SIZEOF_LONG__ is 8 for
x86_64-pc-linux-gnu and 4 for x86_64-w64-mingw32.
Key takeaways
- Read the judge’s own page for the entry you submit to: compiler, library, mode, platform and flags.
- A C++23 library feature needs both a new enough library and a C++23 mode; in the World Finals’ gnu++20 mode none of them is available.
longis 4 bytes on Windows judges such as Codeforces: uselong longorstd::int64_tfor large values.long doubleis plaindoubleon Apple silicon, but has 64 bits of precision on x86-64 judges.- AtCoder zeroes uninitialised locals, which can hide a missing
= 0; build practice code with-Walland-ftrivial-auto-var-init=pattern. - Submit a probe once per judge entry, and build locally with the judge’s compiler family, mode and flags.
Not affiliated
Based on the public pages of Codeforces, AtCoder, LeetCode and the ICPC. MySmartCoPilot is not affiliated with any of them, and their environments may change or differ from what this lesson describes.
References
- Codeforces Command Lines (archived copy) (Codeforces)
- AtCoder language and library list (AtCoder)
- What are the environments for the programming languages? (archived copy) (LeetCode)
- ICPC World Finals programming environment (ICPC Foundation)
- Data Type Ranges (Microsoft)
- Writing ARM64 code for Apple platforms (Apple)
- The GNU C++ Library Manual: Implementation Status (GNU Project)
- libc++ C++23 Status (LLVM Project)
- C++ Standards Support in GCC (GNU Project)
- C++ Support in Clang (LLVM Project)
- 128-bit Integers (GCC manual) (GNU Project)
- Options That Control Optimization (GCC manual) (GNU Project)
- g++ package in Ubuntu 24.04 (noble) (Canonical)
- Working Draft, Programming Languages: C++ (N4950) (ISO/IEC JTC1/SC22/WG21)
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress