Runtime Issues with std::optional in GCC on M2 Mac

89 Views Asked by At

I have found what I believe to be a weird bug with std::optional in GCC on my macbook. I am hoping that someone can either show me that I'm wrong, or offer guidance about where to report it.


Background:

I recently decided that I wanted to learn more about monads, so I started following along with a presentation given at CppConn this past year. (Video here for those interested)

My environment is composed of:

Hardware: Apple M2 Macbook Air
OS:       Sonoma 14.2.1
GCC:      13.2.0 

Initial Problem:

In the following code, I found that I was unable to catch the std::invalid_argument being thrown by std::stoi.

Code:
#include <iostream>
#include <optional>

std::optional<int> convertStrToInt(const std::string& s) {
    std::optional<int> ret;

    try {
        ret = std::stoi(s);
    } catch (...) {
        std::cout << "Caught bad str to int conversion!\n";
    }

    return ret;
}

int doubleValue(int v) {
    return v+v;
}

std::string convertIntToStr(int v) {
    return std::to_string(v);
}

std::optional<std::string> stringDouble(const std::optional<std::string>& opt) {
    return opt.and_then(convertStrToInt)
              .transform(doubleValue)
              .transform(convertIntToStr);
}

int main() {
    std::optional<std::string> result;

    std::optional<std::string> input_1("123");
    result = stringDouble(input_1);
    if ( result.has_value() )
        std::cout << "stringDouble's result for input_1: " << result.value() << std::endl;
    else
        std::cout << "stringDouble has no result for input_1\n";

    std::optional<std::string> input_2("NaN");
    result = stringDouble(input_2);
    if ( result.has_value() )
        std::cout << "stringDouble's result for input_2: " << result.value() << std::endl;
    else
        std::cout << "stringDouble has no result for input_2\n";
    
    return 0;
}
Compile:
g++-13 -std=c++23 std_opt.cpp
Output:
stringDouble's result for input_1: 246
terminate called after throwing an instance of 'std::invalid_argument'
  what():  stoi
Abort trap: 6

Concise Problem:

Given the unexpected result above, I decided to make a more concise program to see if I could better determine the cause.

Code:
#include <iostream>
#include <optional>

int main() {
    try {
        throw std::runtime_error("why?!");
    } catch (...) {
        std::cout << "caught exception\n";
    }

    std::optional<std::string> some_opt("my val");

    return 0;
}
Compile:
g++-13 -std=c++23 exception_test.cpp
Output:
libunwind: _Unwind_GetTextRelBase - _Unwind_GetTextRelBase() not implemented
Abort trap: 6

It is also worth noting, that replacing line 11 above with any other, valid c++ code seems fine. E.g., putting a std::cout seems to work as desired.


Testing in Linux:

To see if this was just a Mac issue, created a container from the gcc:13.2.0 image and copied the above code into it.

As you can see, it works as desired:

# uname -a
Linux 62b6636acd54 6.7.4-200.fc39.aarch64 #1 SMP PREEMPT_DYNAMIC Mon Feb  5 23:05:56 UTC 2024 aarch64 GNU/Linux
# g++ --version
g++ (GCC) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

# g++ -std=c++23 exception_test.cpp
# ./a.out 
caught exception
# g++ -std=c++23 std_opt.cpp 
# ./a.out 
stringDouble's result for input_1: 246
Caught bad str to int conversion!
stringDouble has no result for input_2

What's Next

So... am I missing something? Is this a bug? Is it a bug with GCC on Mac? Is it a bug in libunwind? Are the above two behaviors even part of the same issue? I am at a bit of a loss.

Thanks!

0

There are 0 best solutions below