Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate c++ without exceptions #76

Open
memen45 opened this issue Oct 31, 2022 · 6 comments
Open

Generate c++ without exceptions #76

memen45 opened this issue Oct 31, 2022 · 6 comments

Comments

@memen45
Copy link

memen45 commented Oct 31, 2022

At several locations in the fbe.cpp file exceptions are thrown. Is it possible to generate code without these exceptions?
For example here:

throw std::runtime_error("Cannot get value of CLOCK_REALTIME timer!");

I would like to use fbe in an embedded environment, where exceptions are disabled for performance reasons. However, now I am unable to compile the generated c++ code.

@chronoxor
Copy link
Owner

What should we do instead of throw std::runtime_error/std::invalid_argument/std::logic_error? Should we call abort() or assert() and just return?

@memen45
Copy link
Author

memen45 commented Nov 2, 2022

Some throws are already in #if defined(_WINxx) blocks, so that is not a problem. Also several throws are preceded by asserts already, if I understand correctly, this will std::abort in debug mode, and throw if NDEBUG is defined?

throw std::runtime_error("Cannot get value of CLOCK_REALTIME timer!");

This one does not get compiled, since neither Unix nor WINxx is defined. So no throw, but also no time?

throw std::invalid_argument("Invalid UUID string: " + uuid);

This one does get compiled. As far as I can judge, but please correct me if I'm wrong, this one could be eliminated altogether. Instead of writing to _data directly inside the for loop, you could write to a temporary array. Only when the for loop completed successfully, copy the array to _data. This leaves the _data array filled with zeros in case anything goes wrong. Since you already have operator bool() defined, validity can be checked after construction, right?

For the others (asserts + throw), I think the options are

  • return boolean for success. Simply return false if it failed.
  • just remove the assert and throws. E.g. why should attach(..) throw when an empty array is passed in? The default constructor even sets _data to nullptr, so it would leave the object in proper state.

Of course I only have limited knowledge of the code base compared to you, so you might have different ideas. Looking forward to hear what you think.

@chronoxor
Copy link
Owner

As I see in documentation: -fno-exceptions turns all standard library throw's into a call to std::abort()

Is there also any definition for disabled exceptions? Can you check if __cpp_exceptions definition works in your case:

#if __cpp_exceptions
  void __throw_bad_exception(void)
  { throw bad_exception(); }
#else
  void __throw_bad_exception(void)
  { abort(); }
#endif

@memen45
Copy link
Author

memen45 commented Nov 2, 2022

Just tested, and yes, both __cpp_exceptions and __EXCEPTIONS are defined on normal compile, and not defined when using -fno-exceptions:

#ifdef __cpp_exceptions
    #pragma message "__cpp_exceptions is defined"
#else
    #pragma message "__cpp_exceptions not defined"
#endif

#ifdef __EXCEPTIONS
    #pragma message "__EXCEPTIONS is defined"
#else
    #pragma message "__EXCEPTIONS not defined"
#endif

Is std::abort not a bit of a harsh measure? Or are those aborts not depending on dynamic content of objects? It would be very harsh when receiving a bad external binary/object could abort the internal program.

@chronoxor
Copy link
Owner

I think to replace clock_gettime() runtime exception with std::abort(), because system call should work. And try to skip other exceptions with no action or fill with 0 and return. Hope this will be enough.

@memen45
Copy link
Author

memen45 commented Nov 2, 2022

Sounds good!

One other issue I noticed just now, is that the embedded device (compiling with xc32++ v4.10) is neither unix, nor WINxx. That means some code sections / functions are not in compilation at all, since

#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
...
#elif defined(_WIN32) || defined(_WIN64)
...
#endif

will be empty in the embedded case. Should I open a new issue for that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants