- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am testing some code that developed some unexpected runtime behavior when built with ICC. GCC builds work correctly. Unfortunately, I have not yet been able to reproduce the failure in an isolated example, so I can't post the code directly.
There is an accessor method that checks an optional value and initializes it when necessary. I see an exception thrown (std::bad_optional_access) in the last line, which should not be possible. The value is always assigned if the std::optional's has_value returns false.
// E is an enum class
// o is a reference to std::optional<E>
if (!o.has_value())
{
E value = deriveEnum();
o = value;
}
return o.value();
While the assignment fails, I found that using the 'emplace' method on the std::optional seems to work. Adding the block afterwards, I see the 'second setter' log and no exceptions are thrown.
// E is an enum class
// o is a reference to std::optional<E>
if (!o.has_value())
{
E value = deriveEnum();
o = value;
// I added this to catch the failure to initialize
// And prevent std::bad_optional_access from being thrown
if (!o.has_value())
{
log("second setter");
o.emplace(value)
}
}
return o.value();
Is this related to any known issues with ICC?
The version of ICC I'm using is this:
icpc (ICC) 19.1.2.254 20200623
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This seems to have appeared when using icpc and devtoolset-9. I don't see this when using icpc and devtoolset-8.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Vince,
Thanks for reaching out to us.
I have constructed a sample code from your snippets and tried to reproduce your issue in our environment(Ubuntu). I haven't got any exceptions while running the code.
I am attaching my code and could you please take a look and suggest any changes to reproduce the error.
#include<iostream>
#include<string>
#include<optional>
enum class E : int{ var1 =1,
var2 = 2,
var3 = 3 };
enum E deriveEnum(void)
{
return E::var3;
}
auto accessor(std::optional<E> o){
try {
if (!o.has_value())
{
E value = deriveEnum();
o = value;
std::cout<<"value of o is"<<static_cast<int>(*o)<<std::endl;
/*if (!o.has_value())
{
std::cout<<"second setter"<<std::endl;
o.emplace(value);
}*/
}
return o.value();
} catch(const std::bad_optional_access& e) {
std::cout << e.what() << '\n';
} catch (const std::exception& e) {
std::cout << e.what() << '\n';
} catch (const std::string& ex) {
std::cout << ex << '\n';
} catch (...) {
std::cout<<"exception caught"<<'\n';
}
}
int main() {
std::optional<E> opt = {};
auto value = accessor(opt);
std::cout<<"value is"<<static_cast<int>(value)<<std::endl;
return 0;
}
I have checked the release notes haven't found this kind of issue in Known Limitations.
Please provide your environment details (OS version, GCC version, Kernel Version etc..)
Regards
Prasanth
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Vince,
We haven't heard back from you.
Let us know if the given code is similar to yours or else please suggest any changes.
We are working on it and get back to you.
Regards
Prasanth
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As Prasanth mentioned, we haven't been able to reproduce the issue at our end. Can you provide us a reproducer to investigate?
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, for the lack of replies. I was away from the office for a couple weeks. The example you posted wasn't showing the behavior either. I was able to work around the problem in my own code. I'll see if I can recreate the problem in an isolated example.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Any update on this?
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please update us on this issue. If we don't hear from you in the next few days, we may go ahead and close this thread.
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I had put a workaround in the code, but I just confirmed that the original problem is still there as stated. I have not yet been able to create an isolated example that demonstrates the problem. Due to -ipo and other flags, it takes 15 minutes or more to build and link a release binary. I took the example and dropped it into my release binary using the same storage for optional as my code. It exhibited the problem, logging "bad_optional_access: bad optional access". I am beginning to think that this might be caused by the storage of the structure containing the std::optional values, which is periodically refreshed by calling "m_storage = {};" elsewhere. The m_storage class is a templated container class which is selecting the appropriate structure via getter.
E MyClass::deriveEnum(int c) {
auto& m_e = m_storage.get(1).e; // in my own code the getter uses a different enum
if (!m_e.has_value()) {
E e;
switch (c)
{
case 1: e = E::var1;
case 2: e = E::var2;
case 3:
default:
e = E::var3;
}
m_e = e;
}
try {
return m_e.value();
} catch(const std::bad_optional_access& e) {
LOG("bad_optional_access: %s\n", e.what());
} catch (const std::exception& e) {
LOG("exception: %s\n", e.what());
} catch (const std::string& ex) {
LOG("string: %s\n", ex);
} catch (...) {
LOG("other exception\n");
}
return E::var1;
}
@vindriolo wrote:
I am testing some code that developed some unexpected runtime behavior when built with ICC. GCC builds work correctly. Unfortunately, I have not yet been able to reproduce the failure in an isolated example, so I can't post the code directly.
There is an accessor method that checks an optional value and initializes it when necessary. I see an exception thrown (std::bad_optional_access) in the last line, which should not be possible. The value is always assigned if the std::optional's has_value returns false.
// E is an enum class // o is a reference to std::optional<E> if (!o.has_value()) { E value = deriveEnum(); o = value; } return o.value();
While the assignment fails, I found that using the 'emplace' method on the std::optional seems to work. Adding the block afterwards, I see the 'second setter' log and no exceptions are thrown.
// E is an enum class // o is a reference to std::optional<E> if (!o.has_value()) { E value = deriveEnum(); o = value; // I added this to catch the failure to initialize // And prevent std::bad_optional_access from being thrown if (!o.has_value()) { log("second setter"); o.emplace(value) } } return o.value();
Is this related to any known issues with ICC?
The version of ICC I'm using is this:
icpc (ICC) 19.1.2.254 20200623
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I pulled the m_e field out of the m_storage structure and it still shows the problem when performing reset via "m_e = {};". However, it looks like the problem goes away when I change "m_e = {};" to "m_e.reset();"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I searched our bug database and couldn't find anything related to this one.
v19.1.2 is quite old. Can you try oneAPI 2021.2 HPC toolkit to see if the problem still occurs?
We need to have a reproducer in order to investigate this issue and I will keep this thread open in case you have a reproducer for us.
Thanks for your update.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Were you able to construct a reproducer for us to investigate?
Thanks,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Vince,
We will no longer respond to this thread. If you require additional assistance from Intel, please start a new thread. Any further interaction in this thread will be considered community only.
Thanks,

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page