eggs-cpp / variant

Eggs.Variant is a C++11/14/17 generic, type-safe, discriminated union.
http://eggs-cpp.github.io/variant/
Boost Software License 1.0
137 stars 27 forks source link

Support building without RTTI and exceptions #10

Closed blastrock closed 9 years ago

blastrock commented 9 years ago

This allows building eggs variant in environment where RTTI and exceptions are disabled.

I didn't really know what to do instead of throwing bad_variant_access, I'm open to suggestions.

K-ballo commented 9 years ago

Please target develop to let external tests cycle.

This allows building eggs variant in environment where RTTI and exceptions are disabled.

Thanks! Do you have a need for this configuration?

I didn't really know what to do instead of throwing bad_variant_access, I'm open to suggestions.

Invoking std::terminate sounds as reasonable as anything else. What do standard library implementations do for bad_optional_access, bad_function_call, and the like?

K-ballo commented 9 years ago

The config macros introduced in this PR don't seem to match the design the library uses (they do look somewhat familiar though). Please have a look at include/detail/config and docs/config.md. Let me know if you have any questions.

blastrock commented 9 years ago

Thanks for the answer!

I'll close this PR and make a new one on develop then.

Do you have a need for this configuration?

I'm making a kernel, mostly for fun, and even though I don't have any memory footprint issue yet, I still think that exceptions and RTTI brings in too much overhead. But still, I think there are quite a few people in the C++ industry (like in embedded systems) who need to build stuff without those features.

What do standard library implementations do for bad_optional_access, bad_function_call, and the like?

libcpp's optional does not have any guard for that, their code will probably not compile.

For std::function, they just leave it undefined:

#ifndef _LIBCPP_NO_EXCEPTIONS
    if (__f_ == 0)
        throw bad_function_call();
#endif  // _LIBCPP_NO_EXCEPTIONS
    return (*__f_)(_VSTD::forward<_ArgTypes>(__arg)...);

For std::vector, there's an assert().

As for the config macro name, you suggest something like EGGS_HAS_EXCEPTIONS defined to 0 or 1? I think this name is a bit misleading since other macros are there to test for compiler features, but this one may be used directly by the user to disable the feature, even if the compiler supports it. That's why I went for the #ifndef approach, by default the feature is enabled unless the user adds a -DEGGS_NO_EXCEPTIONS. Anyway, you get the last word, tell me what you prefer :)

K-ballo commented 9 years ago

Do you have a need for this configuration?

I'm making a kernel, mostly for fun, and even though I don't have any memory footprint issue yet, I still think that exceptions and RTTI brings in too much overhead.

I'm familiar with the practice. Since I will have to maintain this configuration once it hits master, I was wondering whether there was an actual need for it. I will gladly merge it knowing that you will be using it in your kernel.

As for the config macro name, you suggest something like EGGS_HAS_EXCEPTIONS defined to 0 or 1?

Nod, more precisely EGGS_CXX98_HAS_EXCEPTIONS and EGGS_CXX98_HAS_RTTI. Please add them to the config.md documentation too.

I think this name is a bit misleading since other macros are there to test for compiler features, but this one may be used directly by the user to disable the feature, even if the compiler supports it.

All the configuration macros are intended to workaround deficient/incomplete implementations. While the library tries to make an educated guess, they can all be specified directly by the user and should be when the library picks don't suit the user needs.

That's why I went for the #ifndef approach, by default the feature is enabled unless the user adds a -DEGGS_NO_EXCEPTIONS. Anyway, you get the last word, tell me what you prefer :)

The library should try to detect whether the feature is present, and default to enabled otherwise. At least for Clang it is trivial, I am unsure about GCC and MSVC but there is probably something of the sort for those too.

It is important that when the library is the one defining the configuration macros, those are not leaked into user code. Check how the macros are currently implemented for reference.