zaphoyd / websocketpp

C++ websocket client/server library
http://www.zaphoyd.com/websocketpp
Other
7.01k stars 1.97k forks source link

Exception-free mode? #438

Open unphased opened 9 years ago

unphased commented 9 years ago

I'm designing a tool that has a component that requires linking or incorporating into a "host" codebase to (portably) augment an application with a websocket server.

The requirement already involves the clang/LLVM compiler environment so it does narrow things down somewhat, but I am slightly worried about C++ exception support being required in order to compile a translation unit that includes websocketpp headers.

In particular I anticipate a hypothetical situation involving the need to link my static library containing a websocketpp server with a codebase that requires -fno-exceptions in its build configuration. Suppose that it magically breaks when that isn't the case...

So there are two things that I am wondering about:

  1. It seems possible to mix-and-match object files which were compiled with and without exceptions, during linking. What are the consequences of this? Presumably the presence of any linked code supporting exceptions will "infect" the executable with exception support.
  2. I see many parts of the API of websocketpp having two versions: one that throws, and one that doesn't. I wonder if it is feasible to support a preprocessor define that can disable all code that throws? This is only reasonable to ask for if none of the internal control flow and algorithms rely on C++ exceptions (which I hope is the case).

As for (2), though, it might not be practical because I see some hints such as this from the changelog

Should make it impossible for exceptions to bubble out of transport methods like io_service::run.

indicating that exceptions are an important part of the logic.

zaphoyd commented 9 years ago

I'm not sure what happens in the case of (1), might be a better question for stack overflow. I'm curious of the answer though.

With respect to (2).. The original core of WebSocket++ required exceptions. I have been slowly working to make this optional by internally using error codes only and offering "exception-full" variants of the user facing methods that simply wrap the error code methods, check for errors, and throw an exception. These "exception-full" variants could either be removed via preprocessor directives or they may never end up in translation units at all due to being unused template methods.

As it stands there is still one remaining internal component that still requires exceptions. I haven't prioritized converting that to be exception free as nobody has actually asked for a truly exception free mode yet.

I don't think it would be a huge amount of work to get the last bit of that done and tested. If that is something that would be important for your project perhaps we should discuss your timeline and what would be involved in getting there?

unphased commented 9 years ago

Hey thanks for the thoughtful response!

I am quite open to contributing to this, so maybe you could provide a little overview of which pieces of code this applies to.

The timeline for my project is mostly at the mercy of my engagement level with my contract work and other life events so in all likelihood, and being realistic about it, i wouldn't need need this for quite some months (estimate a year).

I guess I don't need to sell you on the concept any further, mainly I'm just thinking that having the library work easily in an exception-free environment makes it more attractive from a portability standpoint.

jeremyong commented 8 years ago

+1 for being able to compile and run the library without use of exceptions.

aniongithub commented 6 years ago

+1 from me too.

zaphoyd commented 4 years ago

develop branch has been updated with a number of changes that remove all internal use of exceptions and all external use of exceptions have been moved to explicit wrapper methods. All functions that throw now are not critical to library operation and can be removed. It is possible this will be sufficient on some platforms to build without exceptions. I am continuing to work on compile time config options to optionally fully remove those functions.

zaphoyd commented 4 years ago

@sourjon (and any others interested) The develop branch has been updated with code that completes this feature. _WEBSOCKETPP_NO_EXCEPTIONS_ can now be defined to remove all code that uses either try or throw. When in exception free mode overloads of library functions that throw will not be avaliable. I've tested this lightly with -fno-exceptions and it has worked in preliminary tests. More testing would be greatly appreciated.

This support is about 98% full featured. There are no cases where you lose precise error handling ability by foregoing exceptions. I am tracking one minor situation where exceptions were used to suppress blanket errors thrown during a handler. If exceptions are disabled I think handlers will not throw, but users who disable exceptions at the library level without disabling them at the compiler level might have a strange edge case. I don't like the way that error suppression is being done anyways so I'll be looking for a way to refactor it for other reasons.

There is a bit more work to do on automated testing (I want the test suite to exercise some of the exception free paths) as well as documentation.

There is also a bit more work to do to document and/or better support using the Asio transport in exception free mode. Asio has an exception free mode as well, that you can activate by defining ASIO_NO_EXCEPTIONS. I've also tested compiling with this enabled and -fno-exceptions and it does work in conjunction with the WebSocket++ define. However, there are a number of cases within Asio where the strategy for "no exceptions" simply means the throw function is redefined into a user supplied generic error call rather than translated into an overload that returns error information.

This requires the library user to define this global "asio threw something" hook and deal with the result sensibly. In my sampling of WebSocket++ example programs, there were 4-5 calls to this asio defined throw function. I intend (at some point) to look in more detail at these and confirm whether there isn't an alternative that the core library can switch to. I suspect that there is not. What this means for users of the WebSocket++ Asio transport in exception free mode is that they will need to define an asio::detail::throw_exception<> function and (if desired) find a way to route its output into their exception free error handling.

sourjon commented 4 years ago

@zaphoyd , great! Looking forward to checking it out!