Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

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.

  • Intermediate
  • 20 minutes
  • Examples run with Clang 21.0.0, GCC 16.2.0 and Python 3.14.8
  • By MySmartCoPilot
Free: 20 minutes

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++23 mode, on 64-bit Windows, with -O2, -DONLINE_JUDGE, -static and 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++23 mode on x86-64 Linux, with -O2, -march=native, -DONLINE_JUDGE, -DATCODER and -ftrivial-auto-var-init=zero.
  • LeetCode, C++: Clang 19 with libstdc++ from GCC 14 in C++23 mode, with -O2 and 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++20 mode, on 64-bit Ubuntu 24.04, with -O2, -g and -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.

A solution passes through language mode, standard library, platform and flags before its verdict; judges differ at each layer.solution.cpp1. Language mode-std=c++23, gnu++23or gnu++202. Standard librarylibstdc++ 13, 14 or 15,or libc++3. PlatformWindows: long is 4 bytesLinux: long is 8 bytes4. Flags-O2, AddressSanitizer,-DONLINE_JUDGE, zeroedlocals, stack sizeVerdict

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.

  1. solution.cpp, your source file.
  2. Language mode: -std=c++23 on Codeforces, gnu++23 on AtCoder, gnu++20 at the ICPC World Finals.
  3. 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.
  4. Platform: on Windows, where Codeforces judges, long is 4 bytes; on Linux it is 8 bytes.
  5. 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.
  6. 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 C++ · modern.cpp
// 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.

One file, four builds Python · judges_session.py
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 C++ · portable.cpp
// 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]);
}
The portable file with the same four sets of flags Python · portable_session.py
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:

Type sizes on four targets Python · targets_session.py
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.

Programmer Calculator (Bitwise) Type 2147483647 as a 32-bit signed number and add 1 to see where a 4-byte long ends.

Flags that change what a program does

Four of the judges’ flags change behaviour rather than speed:

  • -DONLINE_JUDGE is defined by Codeforces and AtCoder. The World Finals command line does not define it, so code that reads from a file unless ONLINE_JUDGE is 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=address when 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=zero at AtCoder starts every uninitialised local variable at zero. That hides a common bug, a total that is never set to 0:
uninit_total.cpp C++ · uninit_total.cpp
// 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);
}
The same bug with zeroed and with patterned locals Python · uninit_session.py
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.

Number Base Converter Read FEFEFEFEFEFEFEFE as a signed 64-bit number to get the value the pattern build started from.

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 C++ · probe.cpp
// 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
}
The probe with libc++, and with libstdc++ in two modes Python · probe_session.py
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:

judge_builds.sh Shell · judge_builds.sh
#!/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
The script with GCC 16 as g++, then the four programs Python · reproduce_session.py
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.

Text Diff Paste your program's output and the expected output to see the first line where they differ.

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.

  1. std::println
  2. std::format
  3. std::views::enumerate
  4. std::ranges::to
  5. std::flat_map
  6. Printing a whole vector with std::println
  7. Deducing this, for example in a recursive lambda
  8. #include <bits/stdc++.h>
  9. A long that holds 3,000,000,000
  10. std::mdspan

Hint: find the GCC version that added each library feature, then ask whether the judge’s mode is C++23.

One solution

  1. std::println: Codeforces, AtCoder and LeetCode, but not the World Finals.
  2. std::format: all four.
  3. std::views::enumerate: Codeforces, AtCoder and LeetCode, but not the World Finals.
  4. std::ranges::to: Codeforces, AtCoder and LeetCode, but not the World Finals.
  5. std::flat_map: AtCoder only.
  6. Printing a whole vector with std::println: AtCoder only.
  7. Deducing this: Codeforces, AtCoder and LeetCode, but not the World Finals.
  8. #include <bits/stdc++.h>: all four.
  9. A long that holds 3,000,000,000: AtCoder and the World Finals, but not Codeforces; LeetCode does not say.
  10. 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.

  1. Question 1 of 6 How many bytes does long have on Codeforces' GNU G++23 14.2 entry?

    Choose one answer.

    Show the answer to question 1

    Answer: 4, because the compiler builds for Windows

    The entry is a 64-bit GCC, but it builds for Windows, which keeps long at 32 bits. Clang's predefined macros for x86_64-w64-mingw32 showed __SIZEOF_LONG__ as 4. The C++ standard only asks for at least 32 bits, so use long long or std::int64_t for values above 2,147,483,647.

  2. Question 2 of 6 What is the largest value a long can hold on Codeforces?

    Type a number.

    Show the answer to question 2

    Answer: 2147483647

    A 32-bit signed type holds values up to 2 to the power 31, minus 1, which is 2,147,483,647. The total of 5,200,000,000 in the lesson's sessions would not fit.

  3. Question 3 of 6 modern.cpp uses std::println and std::views::enumerate. Which builds in the lesson compiled it? Choose every one.

    Choose every answer that is right.

    Show the answer to question 3

    Answer:

    • GCC 16 with Codeforces' flags and -std=c++23
    • GCC 16 with AtCoder's flags and -std=gnu++23

    libstdc++ offers its C++23 features only in a C++23 mode, so the gnu++20 build stopped at std::println and views::enumerate. Apple clang's libc++ 22 failed only at views::enumerate, which libc++ added in version 23.

  4. Question 4 of 6 AtCoder builds C++ with -ftrivial-auto-var-init=zero. What does that mean for a solution whose total is never set to 0?

    Choose one answer.

    Show the answer to question 4

    Answer: The total starts at zero there, so the bug can pass on AtCoder and fail on another judge

    The flag initialises every automatic variable that has no initializer with zeroes, so the forgotten = 0 is supplied for you. With pattern instead of zero, the same program printed a huge negative number. -Wall reported the bug with both compilers.

  5. Question 5 of 6 How many bits of precision does long double give on a Mac with Apple silicon?

    Choose one answer.

    Show the answer to question 5

    Answer: 53, the same as double

    Apple's ARM64 notes say long double is identical to double there, and the probe printed 8 bytes and 53 bits. The x86-64 judges give long double 64 bits of precision, so answers computed in long double can differ in their last digits between your Mac and the judge.

  6. Question 6 of 6 Which judge in the lesson does not define ONLINE_JUDGE in its C++ command line?

    Choose one answer.

    Show the answer to question 6

    Answer: The ICPC World Finals

    Codeforces and AtCoder pass -DONLINE_JUDGE; the World Finals command line is -x c++ -g -O2 -std=gnu++20 -static. Code that reads a local file unless ONLINE_JUDGE is defined would try to open that file at the contest.

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.
  • long is 4 bytes on Windows judges such as Codeforces: use long long or std::int64_t for large values.
  • long double is plain double on 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 -Wall and -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

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.