Just keep away from the Google C++ style guide lines. They'll lead you very far astray.
Check out https://github.com/isocpp/CppCoreGuidelines/blob/master/CppC... for a good start on modern C++ style.
Just keep away from the Google C++ style guide lines. They'll lead you very far astray.
Check out https://github.com/isocpp/CppCoreGuidelines/blob/master/CppC... for a good start on modern C++ style.
Huh. I think Google C++ style guide makes a lot of sense. C++, the good parts.
What's wrong with the guide in your opinion?
I know a lot of people might disagree, but the common criticism of Google's C++ style, exceptions, tends to be a misfeature when you need to actually handle the errors.
It puts error handling code far from where errors occur, and where you often have the best chance to deal with it. It also obscures error sources, it's not immediately obvious in local method context just by looking at the source code which calls can throw and which not.
Exceptions also don't undo any I/O that was done, so things might be in pretty bad state -- and it tends to be pretty bad to deal with that a few method calls up.
I like errors to be on my face, even if they're "ugly". You tend to forget about hidden things.
It would be great to have some function annotations to show which exceptions can be thrown, though. But still, keep in mind tha Google's style is pretty much equivalent to having a catch(...) after every call.
There was [0]. It is deprecated and generally discouraged, since it quickly becomes a maintenance nightmare (since you have to include unhandled exceptions for all functions called from that function, etc, all the way down).
The noexcept keyword was actually added to address some of the limitations.
Is there a better way to do it, maybe a static analyzer or IDE warning about possible exceptions?
Another way to express constraints are attributes, which static analyzers (and optimizers) also use. For example, GCC has a number of function attributes [2] to express invariants about code.
[1] http://clang-analyzer.llvm.org/scan-build.html#recommended_d...
[2] https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attribute...
So, you pass file name to your data access library and the file is not there. How are you going to deal with it? Write an error to the log nobody reads and call terminate()? Create a new file and let users guess what happened to the data they expected? Or return an error code?
If you picked the last option (as most people do) - well, bingo, you've just put your error handling far from where the error occurred. The only difference with throwing an exception is that now every function up the call stack needs to check that error code till it reaches the place where you can handle it or, even more likely, till someone forgets to check or chooses to ignore it. Because, unlike Go or Rust, C++ compiler won't help you there.
Error codes don't undo I/O either.
As to "which functions can throw" - let me suggest a simple rule: every function can, unless you can prove otherwise.
Look, there are situations where it makes sense to avoid exceptions, but not for the reasons you listed. Exceptions are the least evil way to handle errors in C++. Google style guide bans them mostly for historical reasons, let's not cargo cult it.
Perhaps return an error code. Which the caller would check and deal with the error. (Besides, I'd be passing a stream object, not a filename.)
I/O is also network packets, graphics on the screen, motor movements.
> P.S. As to "which functions can throw" - let me suggest a simple rule: every function can, unless you can prove otherwise.
Exactly, that's the problem.
(1) There are clever hacks to mimic this behavior to some extent, but I don't even want to go there. If you really want this feature - just use a language that has it.
D on Windows is surprisingly pleasant though.
Rustwin's law: As discussions of C++ grow longer, the probability of a comparison to Rust approaches 1.
The advantage of C++ is that it borrows C's syntax. You can't beat the simplicity of C's syntax. I don't really care about C++ backward compatibility with C, but so far, when I read go, rust, and sometimes D, it looks alien and a little too complex to me.
Not saying C++ templates are good enough, but I think there are not many languages out there with a concise, limited syntax like C or python. Being easy to read and easy to learn is the most important aspect of a programming language. There is python, which really excels in this particular aspect of what makes C great, but I can't really think of any other language which is as much easy to read or comes close.
D is a good contender, but not everybody needs high level, multi paradigm and speed, and are ready to learn something new, especially when you can't reuse C++ libraries.
One think I would like to see in C and C++ is labeled break/continue:
while(foo) {
while(bar) {
break 2;
}
}
and/or baz: while(foo) {
while(bar) {
continue baz;
}
}
Similar to goto, but break baz would exit the while loop, not start it again. And using continue instead of goto is more idiomatic.You come across something in the data the means stop processing that line and skip to the next one.
So you do 'continue 2;' to skip the inner loop, and anything after it (presumably the code that would do something with all those columns you just got) and simply start a new line.
There are lots of use cases.
Obviously there are other ways: You can use a goto, you can set flag variables, you can use functions in the inner loop to give you a way to exit early.
But this type of control flow is easiest to read. Many other language have this BTW. C doesn't.
It's also good for error handling. If you find an error in the inner loop how do you exit that loop, and the outer one? You would do 'break 2;' and exit both loops.
The labeled version is because using a number is prone to errors if someone changes how many loops there are.
Do a search for 'goto' in high quality code and see how many of them can be replaced by this - it's the vast majority.