Featured image of post GCC-13.2.0 Compilation and Installation

GCC-13.2.0 Compilation and Installation

GCC-13 is a major update. In this version, GCC's static analyzer continues to improve, with more C23 and C++23 features, and supports many new x86_64/RISC-V/AArch64 processors. To promote the use of the new C++ standards instead of always writing C++17 or even C++11, I decided to compile and install GCC-13.2.0 to experience the new C++ standards.

# GCC-13.2.0 Compilation and Installation

GCC 13.1 has been released as the first stable version of GCC 13, as the annual feature release of the GNU Compiler Collection.

GCC 13.1 is a major update that adds a Modula-2 language frontend for those interested in some vintage programming. Although there is new GCC Rust gccrs code, it is disabled in v13.1. In this version, GCC’s static analyzer continues to improve, with more C23 and C++23 features, and support for many new x86_64/RISC-V/AArch64 processors.

GCC 13.1 also provides initial AMD Zen 4 (Znver4) support for Ryzen 7000 series and EPYC 9004 series processors, OpenMP offloading improvements, support for issuing diagnostics in SARIF format based on JSON, additional Ada 2022 features, various new C/C++ warnings, support for AMD Instinct MI200 series for AMDGCN backend, Ampere-1A support, Neoverse-V2/Cortex-X3/Cortex-X1C/Cortex-A715 support, and many new Intel CPU supports. GCC 13 added Intel CPU targets for Raptor Lake, Meteor Lake, Sierra Forest, Grand Ridge, Emerald Rapids, and Granite Rapids, as well as related new Intel CPU instruction set extensions such as AMX-FP16, AVX-IFMA, AVX-VNNI-INT8, AVX-NE-CONVERT, RAO-INT, and AMX-Complex.

In order to experience the new features of C++20, GCC 13.1 is also a great choice because it includes support for many new features of C++20. As of the writing of this article, GCC-13.2 has also been released, so I directly chose the latest version.

# Download GCC-13.2.0 source code

wget https://mirror.koddos.net/gcc/releases/gcc-13.2.0/gcc-13.2.0.tar.gz
tar -xzvf gcc-13.2.0.tar.gz
cd gcc-13.2.0

# Start compiling

  • Compilation command:
./contrib/download_prerequisites
mkdir build && cd build

../configure --prefix=/root/software/gcc-13.2.0 \
--with-pkgversion='glibc gcc V13.2.0' \
--enable-checking=release \
--enable-languages=c,c++ \
--disable-multilib \
--enable-bootstrap \
--enable-threads=posix \
--with-system-zlib \
--with-gmp=$GMP_HOME \
--with-mpfr=$MPFR_HOME \
--with-mpc=$MPC_HOME \

make -j$(nproc)
make install

# Set environment variable

# gcc-13.0.2.env
export GCC13_HOME=/root/software/gcc-13.2.0
export PATH=$GCC13_HOME/bin:$PATH
export LD_LIBRARY_PATH=$GCC13_HOME/lib64:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$GCC13_HOME/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$GCC13_HOME/libexec:$LD_LIBRARY_PATH
export CPATH=$GCC13_HOME/include:$CPATH
export INCLUDE=$GCC13_HOME/include:$CPATH
export CC=$GCC13_HOME/bin/gcc
export CXX=$GCC13_HOME/bin/g++
export FC=$GCC13_HOME/bin/gfortran
export F77=$GCC13_HOME/bin/gfortran
export F90=$GCC13_HOME/bin/gfortran
export F95=$GCC13_HOME/bin/gfortran

# Command line test

$ gcc -v

The output is:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/root/software/gcc-13.2.0/libexec/gcc/x86_64-pc-linux-gnu/13.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../configure --prefix=/root/software/gcc-13.2.0 --with-pkgversion='glibc gcc V13.2.0' --enable-checking=release --enable-languages=c,c++,fortran --enable-threads=posix --enable-bootstrap --disable-multilib --with-system-zlib --with-gmp=/root/software/gmp/6.2.1 --with-mpfr=/root/software/mpfr/4.1.0 --with-mpc=/root/software/mpc/1.2.1
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 13.2.0 (glibc gcc V13.2.0)

Successfully compiled and installed.

# Main new features of C++ 20

  • The main new features of C++ 20 are as follows:
  • Concepts: Concepts are type constraints for template parameters, making template code clearer and easier to understand. Concepts allow developers to define an interface that template parameters must satisfy in order to be accepted.
  • Ranges (Ranges Library): This is a significant extension to the Standard Template Library (STL), introducing the concept of “ranges” to support a more declarative way of data processing.
  • Spaceship Operator: <=> is called the spaceship operator, it can compare two values at once and return their relative order (less than, equal to, greater than).
  • Modules: Modules are designed to replace the traditional separation of header files and source files, providing a new compilation unit that can significantly improve compilation time and code organization.
  • Coroutines: Coroutines are a lightweight thread that can switch between different execution points, rather than switching between function calls. Coroutines are a new way to write asynchronous code, allowing functions to pause and resume execution at different points in time without needing callback functions or complex state machines.
    • constexpr improvements: C++20 greatly expanded the scope of code that can be computed at compile time, including allowing virtual functions, try, and catch blocks to be used in constexpr functions.
    • std::to_array for initializer lists: This allows converting initializer lists to std::array, providing a type-safe way to handle fixed-size arrays.
    • Simplification of template syntax: typename and class can be used interchangeably in template parameters, simplifying the template syntax.
    • New standard attributes: Introduced several new attributes, such as [[likely]] and [[unlikely]], to provide branch prediction hints to the compiler.
    • New standard library components: for example, std::span, which provides a view that can represent a part of an array or other contiguous sequence without needing to copy data.
    • New synchronization libraries: For example, std::latch and std::barrier, providing new synchronization primitives for multithreading programming.
    • std::format: This is a new formatting library that provides a type-safe way to format strings.
    • Others, etc.

# Main new features of C++ 23

  • The main new features of C++ 23 are as follows:
    • Lambada
      1. Fix the issue with omitted parameter parentheses ().
      2. Change the scope of the return type at the end of the lambda.
      3. Allow the attributes of support functions to support lambda. This feature is actually supported by many compilers already.
    • Compile-time calculation: Mainly fix some bugs and continue to improve the capabilities of compile-time calculation.
    • Deducing this: Deducing this is one of the most important features in C++23. It actually provides a way to transform the “implicit object parameter” of non-static member functions into an “explicit object parameter”.
      • The main motivation for deducing this is to eliminate the redundancy caused by member function qualifiers.
    • Multidimensional array:
      1. Support multi-dimensional subscript operator, i.e., operator[a, b, c, …].
      2. The standard library introduces std::mdspan.
    • Standard Library:
      • Enhance std::string and std::string_view
      • Enhance std::optional
      • std::flat_map and std::flat_set, replace std::map and std::set.
      • std::stacktrace: Used for expanding the call stack after exception capture, facilitating debugging. Introducing stacktrace into the standard library can be seen as an enhancement of C++ exception handling capabilities.
      • std::expected: Enhanced C++ error handling capability through return values. Similar to std::optional, but std::optional can only represent a normal value and an empty value (std::nullopt). In contrast, std::expected can represent an expected value and an error value, equivalent to a std::variant with two members, but the interface of std::expected is more convenient to use.
      • std::unreachable(): An optimization hint for the compiler, indicating that this point is unreachable. If std::unreachable() is called, the result is undefined behavior.
  • Others:
    • Static operator() and static operator[]
    • Assume expression [[assume(expr)]]
    • size_t literal

# Coroutines example

#include <coroutine>
#include <iostream>
#include <optional>

template<typename T>
struct Generator {
    struct promise_type;
    using handle_type = std::coroutine_handle<promise_type>;

    struct promise_type {
        std::optional<T> current_value;
        static auto get_return_object_on_allocation_failure() { return Generator{nullptr}; }
        auto get_return_object() { return Generator{handle_type::from_promise(*this)}; }
        auto initial_suspend() { return std::suspend_always{}; }
        auto final_suspend() noexcept { return std::suspend_always{}; }
        void unhandled_exception() { std::exit(1); }
        template<typename U>
        auto yield_value(U&& value) {
            current_value = std::forward<U>(value);
            return std::suspend_always{};
        }
        void return_void() {}
    };

    handle_type coro;

    Generator(handle_type h): coro(h) {}
    Generator(Generator const&) = delete;
    Generator(Generator&& o) : coro(o.coro) { o.coro = nullptr; }
    ~Generator() { if (coro) coro.destroy(); }

    T next() {
        if (coro) {
            coro.resume();
            if (coro.done()) {
                coro.promise().current_value.reset();
            }
            return *coro.promise().current_value;
        }
        return T{};
    }
};

Generator<int> generateNumbers(int start, int end) {
    for (int i = start; i <= end; ++i) {
        co_yield i;
    }
}

int main() {
    auto numbers = generateNumbers(1, 5);
    for (int i = 1; i <= 5; ++i) {
        std::cout << numbers.next() << std::endl;
    }
    return 0;
}

Compile command:

g++ -o coroutines coroutines.cpp -std=c++20 -fcoroutines -O3

Run result:

./coroutines
1
2
3
4
5

# Deducing this example

#include <iostream>

struct Test {
    template <typename Self>
    void explicitCall(this Self&& self, const std::string& text) {
        std::cout << text << ": ";
        std::forward<Self>(self).implicitCall();
        std::cout << '\n';
    }

    void implicitCall() & {
        std::cout << "non const lvalue";
    }

    void implicitCall() const& {
        std::cout << "const lvalue";
    }

    void implicitCall() && {
        std::cout << "non const rvalue";
    }

    void implicitCall() const&& {
        std::cout << "const rvalue";
    }
};

int main() {
    std::cout << '\n';

    Test test;
    const Test constTest;

    test.explicitCall("test");
    constTest.explicitCall("constTest");
    std::move(test).explicitCall("std::move(test)");
    std::move(constTest).explicitCall("std::move(consTest)");

    std::cout << '\n';
}
Licensed under CC BY-NC-SA 4.0
本博客已稳定运行
总访客数: Loading
总访问量: Loading
发表了 25 篇文章 · 总计 60.67k

Built with Hugo
Theme Stack designed by Jimmy
基于 v3.27.0 分支版本修改