Google C++ coding style recommends against C++ exceptions, and we don't use them too. For most of the STL library containers one can just ignore the exceptions, because normally they indicate critical errors and are difficult to handle anyway, so crashing is acceptable.
However there is a problem with multi-threading (std::thread), for example entering a non-recursive mutex twice throws an exception. This situation is not critical and could be handled by waiting.
My question is: anyone knows what is Google using as a threading library? Is there any C++ cross-platform threading library that doesn't use exceptions?
Thank you
It should be noted that Google's style guide does not not preclude the handing of exceptions rather the throwing of exceptions. I.e. deal with the problem, but don't make it any worse by throwing more exceptions.
In the case of re-entering a non-recursive mutex: that is clearly a programmer error rather than some unexpected bolt from the blue. The exception should be allowed to propagate up to the calling code so that it can be seen and dealt with as a bug. It should be noted that the Google Test framework does not rely on exceptions, but it can certainly catch and report them.
While Google's style guide takes an extreme position, there is no doubt that exceptions can highly problematic when writing reusable libraries. For example, we found developing with WinCE 6.0 that exceptions got sliced on re-throwing and on ARM platforms couldn't be reliably thrown across DLL boundaries. In addition, catching an exception could take several milliseconds, so they definitely shouldn't be used for non-exceptional circumstances (i.e. 'expected' errors) where real-time performance is required. The clue's in the name really.
The practices in Google's style guide dates back to the early nineties of the previous century, when threads were rather exotic beasts. As such, it doesn't make sense to wonder how that style and threads would mix. If you use "modern" (21st century) techniques like threads, you don't use Google's style guide and vice versa.
IIRC the reason that Google does not use exceptions is that much of their codebase is not exception safe, and they cannot afford to rewrite it.
From their site:
On their face, the benefits of using exceptions outweigh the costs, especially in new projects. However, for existing code, the introduction of exceptions has implications on all dependent code. If exceptions can be propagated beyond a new project, it also becomes problematic to integrate the new project into existing exception-free code. Because most existing C++ code at Google is not prepared to deal with exceptions, it is comparatively difficult to adopt new code that generates exceptions.
Given that Google's existing code is not exception-tolerant, the costs of using exceptions are somewhat greater than the costs in a new project. The conversion process would be slow and error-prone. We don't believe that the available alternatives to exceptions, such as error codes and assertions, introduce a significant burden.
Our advice against using exceptions is not predicated on philosophical or moral grounds, but practical ones. Because we'd like to use our open-source projects at Google and it's difficult to do so if those projects use exceptions, we need to advise against exceptions in Google open-source projects as well. Things would probably be different if we had to do it all over again from scratch.
Personally speaking I much prefer function return codes than exceptions. But regardless of one's own preferences or coding styles, the important thing is to catch problems where they occur, don't let them propagate, persist or cause mayhem.
What I do, especially during development, is on detecting any sort of error in any sort of thread I get the process to freeze itself. On Linux I raise the SIGSTOP signal. The benefit of that is that I can then attach with a debugger and see the whole process in all its broken glory.
Related
The supposed ethos of C++ is "what you use, you pay for". However, this can be quite debilitating due to exceptions and their pervasive use in the STL.
Before anybody says "just turn exceptions on", life is not so generous with the programming environments we must live in. Mine is kernel programming where the execution environment does not provide enough C++ runtime to unwind the stack, etc.
STL containers will throw allocation failure exceptions when they cannot reallocate storage for their underlying backing stores. When exceptions are not enabled in the environment, the program will crash rather mysteriously: I have seen implementations straight-up abort or just assume that the allocation worked even if it did not.
Many C ADT libraries that I have come across deal with this problem upfront by returning an error code or having the error as an output parameter.
What is the "best" C++ way of dealing with this problem?
To clarify
I do not want to use the standard library, I cannot. I am not asking "how do I do that which cannot be done". I am asking: "given a clean slate, how should the container library be built."
That's easy: stop believing you should use the standard library for everything.
The standard library is intended to be the default place you go for functionality. However, that doesn't mean it is appropriate in every situation. Such as kernel programming, for example. This is a fairly niche environment, where you need direct and explicit control over things that the majority of C++ programmers don't care about.
The C++ standard mechanism for signaling failure, particularly of something like internal memory allocation from a container, is to throw an exception. The vast majority of applications will not bother to catch that exception; in the unlikely event that they are out of memory, they just die. Which is fine for them. Returning an error code in these cases is, at best difficult (consider reallocation of a std::vector<std::string>. What happens if one of the inner std::strings is what gets OOM? Who gets the error code? How would you even signal the failure of a constructor, since the exception is thrown by std::strings copy constructor?). And only people who really need to care will care enough to catch it.
You're working in a restricted environment, an environment that the standard library is not designed to handle. So... don't use it in that environment.
My suggesting is to track down a copy of EASTL. It's really designed for this sort of thing. The Github repo I linked you to has some bug fixes and so forth, but it's still mostly the same. It's not a bad bit of code. Their STL-like containers provide most of the interface, so they can be mostly drop-in replacements. But they provide special functionality to specifically control memory allocations. And they don't throw (or at least, you can turn off throwing).
It seems the problem is really your environment. Stack unwinding is not terribly complicated. I can see why you'd want to put some restrictions on it - throwing a 10 MB object is legal C++ - but even in kernel mode you should be able to support throwing std::bad_alloc through non-virtual calls.
With that in mind, the STL design is perfectly sane. The interface requires only minimal exception support, and the implementation can be tailored to the environment.
I'm porting a C++ library to my mbed using the hosted mbed C++ compiler which is basically ARMCC with a configuration that you can't really change. One of the configuration options they decided on (for some unknown reason) is that exceptions are not supported. So a throw and a catch will yield compiler errors.
How exactly can you use the standard C++ library without exceptions? I use some vectors in my library. How do I know if the push_back function actually succeeded? Is there any standard way of knowing if an exception occurred or does it just do an exit(1) or something?
How exactly can you use the standard C++ library without exceptions? I
use some vectors in my library. How do I know if the push_back
function actually succeeded? Is there any standard way of knowing if
an exception occurred or does it just do an exit(1) or something?
You're venturing into very restrictive territory once you disable exception handling in C++.
Some standard library implementations, like Dinkumware's, allows one to disable exceptions. There it's a matter of defining a macro, _HAS_EXCEPTIONS, as 0. STLPort has a similar convention with _STLP_USE_EXCEPTIONS=0.
However, there is no standard definition of what standard libraries should do when exceptions are disabled. Exception-handling, for the most part, is pretty much ingrained into the C++ language. Even dynamic_cast and operator new/new[] throw by default and those are not library features.
There's also a lack of a clear definition of what should happen even for the standard library implementations that don't throw. If a sequence push_back throws in the process of allocating more memory for that sequence, what should happen? Is the element simply not inserted? The standard interfaces of these sequences certainly tells us nothing about when such an error occurs.
Furthermore, a lot of C++ libraries in general will be using functions that do throw like operator new (and not the nothrow versions). As a result, we do venture into a lot of undefined behavior territory once we disable exceptions.
I once had to work in a company which forbid exception-handling since the senior programmers in charge were premature optimizers who preferred C and thought C++ was awful and inefficient (coincidentally, they wrote some of the most inefficient code on the team with a strong preference for linked lists as a default container which caused profiling hotspots to show up left and right due to the sheer number of tiny nodes being allocated/deallocated for everything, but that's another story).
With embedded systems, the argument against exception handling might be a bit stronger, but it does become difficult to rely on C++ in general without it. I think the best you can do without exception-handling is accept a crippled form of C++ without a lot of the standard library parts that throw unless you want to invest a lot of time trying to find workarounds and tricks specific to your particular standard library vendor which might be more trouble than it's worth.
They explain why it's not supported here:
The conventional wisdom (and the advice from the armcc compiler guys)
is that the overhead of exceptions is pretty high and therefore not
appropriate for this sort of domain. For now, we are therefore not
supporting exceptions (it is hard to remove support, but easy to add
it).
We'll definitely look at really understanding the space and time
overheads at some point (mbed isn't really conventional, so perhaps
exceptions are perfect!), but for now you'll have to stick to more
conventional exception handling approaches.
And here:
We don't support exception handling in the compiler, and it is not
planned to add it. But i'd be happy to hear about how you usually use
them in your microcontroller applications, or your experiences! But
for now, you will have to turn to more standard C solutions.
Based on this I can guess the exceptional situations would end up in std::terminate().
I don't think that not supporting exceptions is a legal option in C++ per the language standard. So, you should either make an experiment to see what happens when new or push_back() fails or ask the people behind the compiler.
I have been programming in C++ on and off for about 5 years, why have I never seen exceptions used other than examples for examples sake?
Observation bias at work here.
A significant fraction of C++ code is for systems programming and embedded systems. (After all, C++ is just one of many options for applications programming, and many of the alternatives have fancier RAD environments, but in systems work, it's often the highest level language for which a compiler is available, by a wide margin). And most embedded systems as well as a significant chunk of systems development work have constraints that rule out exceptions.
If because of your focus, you tend to search out this sort of code, it's entirely possible that the C++ code you've seen doesn't use exceptions.
That doesn't mean that there isn't C++ code using exceptions -- there is, and a lot of it. It may just not appear in code designed to solve problems that are interesting to you.
Exceptions are a fairly late addition to the language, so I believe many C++ developers have never learnt to use them properly, and may feel more at ease using traditional (C style) error handling techniques.
I personally think they are indispensable in handling constructor failures (that is the foremost reason they were added to C++ after all), but they also require the correct use of other advanced (YMMV) techniques like RAII or smart pointers to avoid resource leaks.
I have been programming in C++ on and off for about 5 years,
why have I never seen exceptions used other than examples for examples sake?
I'm very curious about this.
I'm very curious about this since in 1996.
Sometime I think in 1996 C++ Exception Handling revolutionized the way I'm writing software.
I remember that I was reading about C++ Exception handling and I immediately understood the implications. Within minutes I was testing what happens, if an exception is thrown from a constructor.
Compilers for UNIX were not ready for C++ Exception Handling until G++ 3.0 I think (whe was this?).
Destructors were called for not constructed memory locations (on the stack) (in case of some exception was thrown).
Destructors were not called for successful constructed objects (on the stack) (in case of some exception was thrown).
delete was not called in case of an object created with new threw an exception from the constructor.
Compilers for Windows and OS/2 were ready in 1996/1997. They worked.
I remember Borland C++ for OS/2 and IBM CSet2 and Windows Visual C++.
Finally there was a method to abort construction of an object.
Finally one could allocate an object inside a constructor AND rely on the successful construction of this object in some other constructor.
Somehow I found out about all the rules. Not from books!
Years later books came out, claiming that C++ Exception Handling is a good way to catch array-out-of-bounds error or other problems for which I never stopped using assert.
Finally there was an easy method to provide the caller with complex information about some error without relying on stderr. Finally one did not need to debug some complex piece of software to find out, what was failing.
I cannot take people seriously, which are not using C++ Exception Handling.
It is impossible to check every fallible call.
It is impossible to reach the same level of quality of software without using C++ Exception Handling.
Why are such people still hired?
Why are there still platforms, which do not provide C++ Exception Handling.
I would never consider writing software for such a platform,
in the same way I would refuse writing a complex application in assembly code.
Curious. I work in C++ regularly, and it's been at least ten
years since I've seen any C++ code which doesn't use exceptions.
Anytime you have to propagate an error up a significant number
of stack frames, you use an exception.
Several reasons come to mind:
Exceptions shouldn't be very visible, since they are designed to be thrown deep in the bowels of a library and caught somewhere high up in the call stack (even as high as main()).
They are intended to signal exceptional (i.e., rare and unexpected) faults. For example, failure to open a file isn't particularly exceptional. So, by default, the iostream library doesn't throw an exception when it fails to open a file.
Exceptions are very expensive to throw, which encourages adherence to the design intent.
C++ libraries that throw exceptions don't interface easily with C programs.
I could say the same thing and it would not be biased a lot, if i define that this is true for a Microsoft world and RAD.
I think it is because today you don't use C++ programs per se but rather a mixture of high level language using C++ libraries. And often you have a managed-unmanaged boundary.
Throwing and catching exception through this boundary is like lighting a firecracker in you ass :) - [read mem leak or worse]
Moreover if you use COM objects you have to use COM exceptions, so the usage of standard C++ exception must reside internally in a often small library. In small libraries you dont have a need to use exceptions.
Because there is a huge discrepancy between "real-world" code and "text-book" code.
I work in a "large" software company and can honestly tell you that the stuff you see in production follows nearly 0% of the good practices you read about in good books.
Take Scott Meyers' Effective C++ book as an example. Should be a copy on every software engineer's desk, from east coast, to west.
Exceptions are too advance for beginners so these are not always shown in the examples, especially on books.
I'm speaking of desktop applications for Windows. In my observation (YMMV too), earlier phase of the development probably until initial releases. Many developers doesn't think of exceptions early on. That is why there are few codes with exception handling but if you had like 2 or 3 releases already or if your on maintenance phase, exceptions are being considered due to various deployment environments through error reports from customers.
Several reasons come to mind:
Exceptions shouldn't be very visible, since they are designed to be
thrown deep in the bowels of a library and caught somewhere high up
in the call stack (even as high as main()).
I don't know what you mean with "Exceptions shouldn't be very visible".
But I agree that catch-blocks should be rare -- and they are usually in main.
They are intended to signal exceptional (i.e., rare and unexpected)
faults. For example, failure to open a file isn't particularly
exceptional. So, by default, the iostream library doesn't throw an
exception when it fails to open a file.
that the iostream library does not throw exceptions makes it kind of unuseable.
Hiding errors from the caller!
This is so C like.
Exceptions are very expensive to throw, which encourages adherence
to the design intent.
Usually Exceptions are for system calls failing.
Since writing to a file or opening a file is not really inexpensive,
one would not care about Exceptions being expensive.
Also having to check for success is more expensive than using C++ Exception Handling.
Usually one would not create a try-catch block inside a time critical part of code.
C++ libraries that throw exceptions don't interface easily with C
programs.
What is C? Ah yes -- I remember -- something I gave up around 1996. Remember Turbo Pascal?
Exemptions are not used in examples because it is rarely the focus of many of the questions or something you want to know in the first place.
I've been writing a number of network daemons in different languages over the past years, and now I'm about to start a new project which requires a new custom implementation of a properitary network protocol.
The said protocol is pretty simple - some basic JSON formatted messages which are transmitted in some basic frame wrapping to have clients know that a message arrived completely and is ready to be parsed.
The daemon will need to handle a number of connections (about 200 at the same time) and do some management of them and pass messages along, like in a chat room.
In the past I've been using mostly C++ to write my daemons. Often with the Qt4 framework (the network parts, not the GUI parts!), because that's what I also used for the rest of the projects and it was simple to do and very portable. This usually worked just fine, and I didn't have much trouble.
Being a Linux administrator for a good while now, I noticed that most of the network daemons in the wild are written in plain C (of course some are written in other languages, too, but I get the feeling that > 80% of the daemons are written in plain C).
Now I wonder why that is.
Is this due to a pure historic UNIX background (like KISS) or for plain portability or reduction of bloat? What are the reasons to not use C++ or any "higher level" languages for things like daemons?
Thanks in advance!
Update 1:
For me using C++ usually is more convenient because of the fact that I have objects which have getter and setter methods and such. Plain C's "context" objects can be a real pain at some point - especially when you are used to object oriented programming.
Yes, I'm aware that C++ is a superset of C, and that C code is basically C++ you can compile any C code with a C++ compiler. But that's not the point. ;)
Update 2:
I'm aware that nowadays it might make more sense to use a high level (scripting) language like Python, node.js or similar. I did that in the past, and I know of the benefits of doing that (at least I hope I do ;) - but this question is just about C and C++.
I for one can't think of any technical reason to chose C over C++. Not one that I can't instantly think of a counterpoint for anyway.
Edit in reply to edit: I would seriously discourage you from considering, "...C code is basically C++." Although you can technically compile any C program with a C++ compiler (in as far as you don't use any feature in C that's newer than what C++ has adopted) I really try to discourage anyone from writing C like code in C++ or considering C++ as "C with objects."
In response to C being standard in Linux, only in as far as C developers keep saying it :p C++ is as much part of any standard in Linux as C is and there's a huge variety of C++ programs made on Linux. If you're writing a Linux driver, you need to be doing it in C. Beyond that...I know RMS likes to say you're more likely to find a C compiler than a C++ one but that hasn't actually been true for quite a long time now. You'll find both or neither on almost all installations.
In response to maintainability - I of course disagree.
Like I said, I can't think of one that can't instantly be refuted. Visa-versa too really.
The resistance to C++ for the development for daemon code stem from a few sources:
C++ has a reputation for being hard to avoid memory leaks. And memory leaks are a no no in any long running software. This is to a degree untrue - the problem is developers with a C background tend to use C idioms in C++, and that is very leaky. Using the available C++ features like vectors and smart pointers can produce leak free code.
As a converse, the smart pointer template classes, while they hide resource allocation and deallocation from the programmer, do a lot of it under the covers. In fact C++ generally has a lot of implicit allocation as a result of copy constructors and so on. As a result the C++ heap can become fragmented over time and daemon processes will eventually fail with an out of memory error even though there is sufficient RAM. This can be ameliorated by the use of modern heap managers that are more fragmenttation resistant, but they do this by consuming more resource up front.
while this doesn't apply to usermode daemon code, kernel mode developers avoid C++, again because of the implicit code C++ generates, and the exceptions C++ libraries use to handle errors. Most c++ compilers implement c++ exceptions in terms of hardware exceptions, and lots of kernel mode code is executed in environments where exceptions are not allowed to be thrown. Also, all the implicit code generated by c++, being implicit, cannot be wrapped in #pragma directives to guarantee its placement in pageable, or non pageable memory.
As a result, C++ is not possible for kernel development on any platform at all, and generally shunned by daemon developers too. Even if one's code is written using the proper smart memory management classes and does not leak - keeping on top of potential memory fragmentation issues makes languages where memory allocation is explicit a preferred choice.
I would recommend whichever you feel more comfortable with. If you are more comfortable with C++, your code is going to be cleaner, and run more efficiently, as you'll be more used to it, if you know what I mean.
The same applies on a larger scale to something like a Python vs Perl discussion. Whichever you are more comfortable with will probably produce better code, because you'll have experience.
I think the reason is that ANSI C is the standard programming language in Linux. It is important to follow this standard whenever people want to share their code with others etc. But it is not a requirement if you just want to write something for yourself.
You personally can use C or C++ and the result will be identical. I think you should choose C++ if you know it well and can exploit some special object oriented features of it in your code. Don't look too much to other people here, if you are good in C++ just go and write your daemon in C++. I would personally write it in C++ as well.
You're right. The reason for not using C++ is KISS, particularly if you ever intend for someone else to maintain your code down the road. Most folks that I know of learned to write daemons from existing source or reading books by Stevens. Pretty much that means your examples will be in C. C++ is just fine, I've written daemons in it myself, but I think if you expect it to be maintained and you don't know who the maintainer might be down the road it shows better foresight to write in C.
Boost makes it incredibly easy to write single threaded, or multi-threaded and highly scalable, networking daemons with the asio library.
I would recommend using C++, with a reservation on using exception handling and dynamic RTTI. These features may have run time performance cost implications and may not be supported well across platforms.
C++ is more modular and maintainable so if you can avoid these features go ahead and use it for your project.
Both C and C++ are perfectly suited for the task of writing daemons.
Besides that, nowadays, you should consider also scripting languages as Perl or Python. Performance is usually just good enough and you will be able to write applications more robust and in less time.
BTW, take a look at ACE, a framework for writting portable network applications in C++.
llvm/clang are considered good C++ code bases. I wonder why C++ exceptions arenot used in them at all?
Memory is managed using something like pools, and erros are reported with returnd values and codes like in C. They even wrapping operator new to be placement new that returns error and not exception when no memory.
Do you have idea why llvm philosophy is not to use C++ exceptions when most books recommend using them?
Chris Lattner recently clarified this issue in the LLVM project coding standards.
Not using exceptions and RTTI reduces executable size and reduces overhead. (You might argue that zero-cost exceptions have no overhead unless thrown. At a minimum, they actually break up the code into smaller basic blocks and inhibit some types of code motion.)
Writing exception safe c++ code is a difficult task.
Turning off exceptions can speed up code execution and reduce code size.
Maybe this is related.
Depending on your compiler and your code, a program that uses exceptions can be faster or slower than an equivalent program that disables and doesn't use exceptions. Also the one that uses exceptions may be larger or smaller.
Every error handling strategy incurs some cost, and I expect that the LLVM developers considered their situation and found that disabling exceptions was the better decision for LLVM.
My recommendation, and the recommendation I have most seen from experts, is to use exceptions to report failures unless you have some specific, solid reason not to. If your reason is performance, it would be wise to base your choice on profiling. Remember that it is vital to compare code that uses exceptions to code that doesn't, but still handles errors correctly.
I think this stems from another guideline: Use assert liberally
Normal error conditions are treated using error codes.
Exceptional error conditions are treated via assert.
I would say that an assert is an even harder exception: you definitely cannot ignore it ;)
Do most books recommend using them? I know most books on C++ programming cover them because they are part of the language, but I don't think I have seen a book that said to prefer them to error codes or other methods of error handling. In fact I would say most books implicitly do not recommend using exceptions because they don't cover how to write good exception safe code.
As far as LLVM being good code and it being not exception based code, the two concepts are largely orthogonal. Code can be cleanly written with or without exceptions.
Seems it is not a llvm philosophy to avoid exceptions. At least I found nothing about exceptions in the coding standard (http://llvm.org/docs/CodingStandards.html), so it is up to developer.
Why it is not widely used? AFAIK exception support was implemented in llvm not so far, so it was not possible to compile llvm for llvm itself :). So it can be just a historical reason to avoid exceptions.