Writing C++ efficiently
category: code [glöplog]
Quote:
being used to pretty high level OO features, coding C++ just feels awful to me.
Yeah C++ does what it can, I think, but it is a low-level language deep down so what can you do. Still, if you're used to Java why wouldn't you at least want classes available in your C projects?
Well, to each his own, of course. Although, "coding C++" is still an odd thing to say given that C++ really isn't anything more than you want it to be. It can be plain C, or it can be C with classes and polymorphism, or C with templates, even C with garbage collection. Not that I care all that much. You can certainly write good code in plain C, and I guess for some people less is more. :)
i don't want c++ classes. being used to "more advanced" OO models, my opinion is (and probably will forever be), classes in c++ are a hack. i don't like friend classes, if i compare pure virtual classes to interfaces, i prefer interfaces, comparing multiple class inheritance to scala traits, both are a nightmare, making the type system needlessly complex (although there are cases at which they come in handy of cause, but both constructs should only be used by advanced programmers), different cast types, different pointer types, backwards compatibility to C making it possible to hack the shit out of C++ using pointer arithmetic an embedded turing complete language interpreted by the compiler (i talk about templates) and whatsoever. and besides: i simply don't like the class declaration syntax and the namespace concept. of cause it is possible to write really good code in C++ as it gives all the freedom you can think of. the freedom has a price though: freedom. my opinion is: give up some features and gain power. some people compare programming languages to tools. in that comparison C++ would be like a huge leatherman including anything from screw drivers to air hammers and bulldozers. if you want to build a street: use the latter, if your target is to fix the fridge, use the former. as a beginner it is hard to understand what you're actually doing. as said: you need years (i wouldn't be surprised if it's decades) of experience to be a C++ master.
It takes years to realize that it doesn't have to take years, to be a C++ master :)
It takes years to realise it does not take years to realise it does not take years to be a C++ master.
Except when it doesn't.
Having learnt C++ before Java, maybe sometimes I think C++ too much.
I lack the ability to return a const or take a const reference as a parameter to some method. And I don't know of a way around that in Java.
Whenever I do C++, sometimes things don't work as I would expect, but then it turns out there is a valid reason for it on the implementation side ; and there is also some design pattern to work around it.
I'm sure people who started with another language will encounter the reverse problem. (exceptions specifications is one example).
The mix with C can get annoying sometimes, but nothing an ugly template can't work around, right ?
I lack the ability to return a const or take a const reference as a parameter to some method. And I don't know of a way around that in Java.
Whenever I do C++, sometimes things don't work as I would expect, but then it turns out there is a valid reason for it on the implementation side ; and there is also some design pattern to work around it.
I'm sure people who started with another language will encounter the reverse problem. (exceptions specifications is one example).
The mix with C can get annoying sometimes, but nothing an ugly template can't work around, right ?
xyz,
doomdoom, thanks for the thorough analysis! in hindsight, i'm a bit ashamed that i didn't see it - how you describe things is basically how i'd code it, i guess (the static Create method is basically how you'd do OO-ish in C, just using the syntactical goodness plus solid inheritance from C++ - real nice). deep inside maybe i was also blinded about the fact that that article was written by Martin Sustrik. That guy kicks major ass, given that he made ZeroMQ. ZMQ rocks bottoms.
to all, i don't see what you don't like about exceptions. exceptions are teh shit! i've written a bunch of small projects (embedded stuff) in c-with-exceptions, in fact.
Quote:
ON ERROR RESUME NEXT \o/for my own (pet-)projects, I've built me a language that has a feature I call "uncritical" exceptions -- such an exception propagates just to the caller level,
if it is not caught there, it will automatically be discarded.
doomdoom, thanks for the thorough analysis! in hindsight, i'm a bit ashamed that i didn't see it - how you describe things is basically how i'd code it, i guess (the static Create method is basically how you'd do OO-ish in C, just using the syntactical goodness plus solid inheritance from C++ - real nice). deep inside maybe i was also blinded about the fact that that article was written by Martin Sustrik. That guy kicks major ass, given that he made ZeroMQ. ZMQ rocks bottoms.
to all, i don't see what you don't like about exceptions. exceptions are teh shit! i've written a bunch of small projects (embedded stuff) in c-with-exceptions, in fact.
skrebbel, technically that's not the same thing, though ;)
If it interests you, here's a small real-life example
(a simple .wav loader)
note how the try..catch block in the test code is only required for more detailed error info, it can be left out if the boolean return value is all you're interested in
also note how lazy I was to only implement a single WavIO::Fail exception :D
If it interests you, here's a small real-life example
(a simple .wav loader)
note how the try..catch block in the test code is only required for more detailed error info, it can be left out if the boolean return value is all you're interested in
also note how lazy I was to only implement a single WavIO::Fail exception :D
Hehe. I was wondering about those "uncritical exceptions". Should I find it funny that you end up manually propagating them to the caller, because the very idea of an uncritical exception is flawed? :) Anyway, just so the discussion doesn't risk moving forward, just look at this function:
And now how it looks with RAII and exceptions:
The only way in which the former version offers more functionality is that it allows for including "SaveLocal" in the exception message, but that's really debug information that you can find in a stack trace anyway.
Not that it matters. Now I'm curious about the motivation for creating this language.
Code:
public static SaveLocal(String _filename, FloatArray d, int _sampleRate, _numCh) : boolean {
return = false;
File f;
if(f.openLocal(_filename, IOS_OUT))
{
try return = SaveStream(f, d, _sampleRate, _numCh);
catch(UncriticalError e) throw e;
finally f.close();
}
else throw Fail("SaveLocal: failed to open file \""+_filename+"\".");
}
And now how it looks with RAII and exceptions:
Code:
public static SaveLocal(String _filename, FloatArray d, int _sampleRate, _numCh) : boolean {
File f;
f.openLocal(_filename, IOS_OUT);
return = SaveStream(f, d, _sampleRate, _numCh);
}
The only way in which the former version offers more functionality is that it allows for including "SaveLocal" in the exception message, but that's really debug information that you can find in a stack trace anyway.
Not that it matters. Now I'm curious about the motivation for creating this language.
The basic idea of these "uncritical" exceptions is that you are not forced to put a try..catch around every piece of code that can throw such an exception.
If you do, you can get more detailed error info, if you don't you have to do with e.g. the return value of a function (if it has any).
for example, instead of
you could write
without risking your whole app fall back to a top-level exception handler.
"critical" / regular exceptions are supported, too, of course.
The whole language builds upon the RAII principle, btw. There is no garbage collector but still no need for a delete keyword.
The motivation ? It was interesting to write it and I find it useful and fun for writing my tools.
If you do, you can get more detailed error info, if you don't you have to do with e.g. the return value of a function (if it has any).
for example, instead of
Code:
// Load
try {
b = WavIO.LoadLocal("samples/housyriff_C_126.wav", sam, sampleRate, numCh, null, null);
if(b)
{
trace "[...] loaded sample len="+(sam.numElements / numCh)+" #ch="+numCh+" rate="+sampleRate;
}
trace "b="+b;
}
catch(WavIO::Fail e) {
trace "[---] caught "+e.fullName+": \""+e.message+"\".";
}
you could write
Code:
// Load
b = WavIO.LoadLocal("samples/housyriff_C_126.wav", sam, sampleRate, numCh, null, null);
if(b)
{
trace "[...] loaded sample len="+(sam.numElements / numCh)+" #ch="+numCh+" rate="+sampleRate;
}
trace "b="+b;
without risking your whole app fall back to a top-level exception handler.
"critical" / regular exceptions are supported, too, of course.
The whole language builds upon the RAII principle, btw. There is no garbage collector but still no need for a delete keyword.
The motivation ? It was interesting to write it and I find it useful and fun for writing my tools.