1

this is my first question here, so feel free to ask for further information if needed.

EDIT: After the bot encouraged me to clarify my problem and state what I'd like to do: I would like to use C++ 20 features such as ´std::jthread´ and run the programs on a MacBook with Apple Silicon (M1). Since Clang compilers don't support jthread and other C++ 20 extensions yet, I tried using g++ which had other problems. Below I noted the exact compiler version of g++ and I would like to know if there is anything wrong with my tools or my runtime, since the program I'd like to run seems not obviously wrong according to the comments.

The described problem arose when I tried to use std::jthread on Mac (Apple Silicon) platform first. Since Clang compilers don't support jthread yet I switched to g++ provided by brew which worked fine at first. After adding exceptions to the code, I got very stange behavior. It was not possible to catch any exception.

From my understanding having exceptions in multi-threaded programs works, if they are caught in the thread where they were thrown. There are more evolved constructs with std::async that can pass them to other threads, but this is not the point here.

Since Clang compilers don't support the C++20 features I'd like to use here, I'd prefer to use g++. Is there any fundamental problem with that? Is the g++ compile known to not work properly on my platform?

To narrow the problem down, I created a minimal example consisting of a CMakeLists.txt and a main.cpp file.

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(testexception LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(testexception main.cpp)

main.cpp

#include <iostream>
#include <thread>

using namespace std;

class T {
public:
    T() {
        try {
            throw std::runtime_error("exception in class");
        }
        catch (const std::runtime_error & e) {
            std::cout << "Caught: " << e.what() << std::endl;
        }
    };
    ~T() {
        cout << "Destructor" << endl;
    };

    thread m_t;
};

int main()
{
    cout << "Throw an exception in main: " << endl;
    try {
        throw std::runtime_error("exception in main");
    }
    catch (const std::runtime_error & e) {
        std::cout << "Caught: " << e.what() << std::endl;
    }
    cout << "That worked as expected. " << endl << endl;


    cout << "Instantiate T:" << endl;
    T test_instance;
    cout << "Worked as expected." << endl << endl;

    return 0;
}

I compiled it on an MacBookAir (M1) running Sonoma 14.4.1 with the following compilers:

  • Apple clang version 15.0.0 (clang-1500.3.9.4)
  • g++-13 (Homebrew GCC 13.2.0) 13.2.0

The output of the Clang binary:

Throw an exception in main: Caught: exception in main That worked as expected.

Instantiate T: Caught: exception in class Worked as expected.

Destructor

The ouput of the g++ binary:

Throw an exception in main: terminate called after throwing an instance of 'std::runtime_error' what(): exception in main

My observations:

  • When compiled on g++ any exception thrown terminates the program
  • If there is no code in ~T(), it does not happen
  • If there is no member of type std::(j)thread, it does not happen
  • If no instance of T is instantiated, it does not happen
  • If compiled on a Linux x86 g++, it works fine
8
  • I've also run it successfully with g++12 on a Raspberry Pi (i.e. ARM), and since it looks simple enough with no attempts to do anything sneaky, I'd join the crowd that says the compiler or library is somehow broken... Commented Mar 26, 2024 at 9:59
  • cannot reproduce godbolt.org/z/bf4hWvxo3 Commented Mar 26, 2024 at 10:14
  • 1
    though, I would try -pthread. I never understood it completely, but I have seen gcc produce weird results when the flag is ommited (compiles, links, but produces runtime errors) Commented Mar 26, 2024 at 10:16
  • btw all the exceptions in your code are thrown and caught in the main thread. No second thread is actually created. Commented Mar 26, 2024 at 10:17
  • Adding -pthread via add_compile_options(-pthread) didn't help. godbolt.org/z/bf4hWvxo3 shows that it runs correctly on x64 which I stated. Somehow the program seems not to run when compiling it with ARM64 gcc: godbolt.org/z/KxdaaYaxK And yes, it is not even necessary to throw the exceptions somewhere else than in main. Commented Mar 26, 2024 at 12:05

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.