Skip to content

Generate c++ without exceptions #76

Open

Description

@memen45

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.

Activity

  1. chronoxor commented on Nov 1, 2022

    @chronoxor
    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?

  2. memen45 commented on Nov 2, 2022

    @memen45
    Author

    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.

  3. chronoxor commented on Nov 2, 2022

    @chronoxor
    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
    
  4. memen45 commented on Nov 2, 2022

    @memen45
    Author

    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.

  5. chronoxor commented on Nov 2, 2022

    @chronoxor
    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.

  6. memen45 commented on Nov 2, 2022

    @memen45
    Author

    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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions