How to convince any C developer to dump gcc and use clang
fseek.me
fseek.me
Obviously, clang does not mean to attract C++ developers. For a while, I'd been adamant about developing in C and not C++. One day I discovered that I'd hand-coded a vtable in order to allow polymorphism in structures of function pointers. The next day, I halved the project complexity by writing 3 classes and changing a flag in the make configuration.
I use Gnu make through the Eclipse CDT on Ubuntu. It's a clunky and ugly toolchain/IDE combo that took days to configure. It compiles C, C++, CUDA and Brook+ in the same project across 3 different computers. A better C frontend would be nice, but I do not look forward to getting that working with everyone else in this chain.
I've found myself in a similar situation. I am writing embedded software which needs to be as portable as possible, but I've found myself starting to implement polymorphism and objects in C. I am tempted to ignore platforms that lack a C compiler and switch to C++, but the reduced predictability of runtimes has kept me from doing so thus far.
I had a 2x speedup a few years ago on math-heavy code (FFTs) by switching from gcc 4.2 to gcc 3.4 -- apparently there was a known issue in gcc's optimizer where it would flag too many values as "keep this in a register" and end up spending lots of time moving data to and from the "register overflow space" on the stack. (I don't know if this has been fixed -- as I said, it was a few years ago that I ran into this issue.)
file.cpp:65: error: please have a look at this line and see if anything jumps out at you.
as that is basically all GCC C++ errors are good for. g++ [options] | sed -e 's/^(.*: (error|warning):).*/\1 please have a look at this line and see if anything jumps out at you/'If you have to use someone else's macros you can use a wrapper function with exactly the same effects.
Also avoid #define constants not related to compilation or pre-processing themselves.
Readable code > unreadabe code. Same counts for compiled binaries.
I have the following macro in a program I'm writing right now:
#define DEF(f)static A f##_n(A x);A f(A x){ \
return r1m(f##_n,x);}static A f##_n(A x)
Turning this into a function is impossible: functions can't define functions in C.Here's another one:
#define DEF(f)static A f##_n(void);A f(void){ \
static int d=0;static A x=0; \
if(unlikely(!d))d++,x=f##_n(); return x;} \
static A f##_n(void)
Ignoring the function composition problem, assume you want to implement the semantics here.If I type this nonsense out for the 60 (or so) times its used, it is likely I'll make a typo that will be difficult to catch.
If I build the table at run-time (roughly the same amount of code), then I accept a run-time cost for something that will be called very frequently.
If I build a table at compile time and fill it at startup, then my program takes longer to start. Maybe if I put a splash screen up my users will forgive me, but that seems dishonest.
A long time ago, programmers did abuse macros as a kind of poor-compiler's inlining, and your advice is good for that: people shouldn't be doing that, and legacy code where it exists should be fixed.
However macros are great for composition. They can greatly improve the readability of some otherwise repetitive code, and while they can be used for evil, they could also be used to solve problems.
I don't know the context of that source, so I can't make a proper reply to how to work around that. Is it really necessary to put it in the pre-processor? Does it change that often? Perhaps you can script it before pre-processing and compiling. It depends a lot on the design's context, this is probably a bad guess but the point is more often than not there are ways to avoid or minimize macro-hell scenarios, IMHE.
I suppose I think the fact it's not more common has to do with this knee-jerk reaction to avoid macros like some kind of plague.
Regarding your other point, I agree: at a certain point hacking up the DSL in perl or lisp is going to give enough greater flexibility that it's going to be worth the additional complexity (to the build system, documentation, programmer-requirements, etc).
-E Stop after the preprocessing stage; do not run the compiler proper.
The output is in the form of preprocessed source code, which is
sent to the standard output.
Input files which don't require preprocessing are ignored.
Take the output of that, compile it, and you will typically get a sensible error message.What this feature needs now is code correction on the fly. Any error reporter smart enough to ask "did you mean 'x'?" should allow me to answer "yes", and write the changes to the file. That would sell clang to a lot of people.
integration with an IDE or vim/emacs + incremental compilation ==> smart error messages and corrections 'on the fly' while you're typing! sort of like how Eclipse gives you sqiggly line warnings almost instantaneously after you finish coding a line
a quick search yields http://clang.llvm.org/performance.html (favourable, but somewhat skewed results). http://forums.cocoaforge.com/viewtopic.php?f=10&t=21016 indicates improved compile times, but it's purely anecdotal.
That said, does anyone else have any experience moving a performance-centric or cross platform project to clang?
Some stuff is starting to emerge, but we're still largely dependent on tests to catch stupid mistakes. When I'm chasing down a bug, it would be nice to have a variety of tools to throw at the problem.
As a contrast, I had the impression that the Python guys care more about this in their code. They also avoid eval and other runtime code generation. (Though I do not if that's related.) It seems these two languages are further apart than in their culture than anything else.
Meanwhile, I got seduced by gcc's nested functions which are not supported by clang. Apparently they are non-trivial in clang so won't appear soon if at all.
Two incompatible mechanisms for function decomposition are annoying.
("blocks" does a lot more, but for the afflicted project I don't need that. Just nested functions would be spiffy, it saves the plethora of arguments being passed to each function if you keep them at file scope.)
By all means play with closures. I don't mean to discourage the original poster from experimenting. I am just pointing out some irony in the context of gcc and clang. Clang is forced to implement nonstandard gcc extensions. I do not see this as a good thing for languages that are essential building blocks and which people have put a lot of work into standardizing. Software development doesn't need to be so ephemeral.
You are assuming that C programmers need to be helped.
The beauty of C lies in its simplicity, not in its features. That's what has kept C alive to this day despite its shortcomings, and despite the existence of C++.
C does not need new constructs. C needs to be kept as simple and as close as possible to the hardware, it needs to continue to be a high-level assembly. That's what C is mostly used for.
If you feel C needs more features, you are probably using the wrong language for the job.
First: organization. If I grab a chunk of function and put it in nicely named subfunction, even if it is only called once it lets me keep each function to a nice size. This could be done with a static function, but then you always have to think: "What else in this file might call this function?"
Second: (And much more empowering) Gathering together repetitious code can be cleaner. Consider implementing some network protocol. You will probably have a "get next byte from buffer" function which will need access to the buffer, the current position, the number of valid bytes in the buffer, and who knows what else. You could make this a static function and pass all the arguments in, correctly, each time and if you only need a single value back that works. With a lexically scoped subfunction you can just reference these in the outer scope and if you need to set an error condition or message just set it in the outer. Very clean. No scary runtime code.
GCC is not perfect, but works well enough, is stable enough, that to switch without a strong argument is going to be a slow process at best.
>> often beats every other C compiler out there
Microsoft and Intel are well-known to generate better code than GCC. So I don't know what you are referring to with "every other C compiler out there."My point is Clang is good but friendly error messages is not the only reason I would change to Clang.
First we need full C++ coverage in clang. Onward!
Orders of magnitute more than just for the error messages.
In the second error message clang found that `horisontal` doesn't exist and suggested `horizontal`. That's fair enough. The last error message actually assumes the code said `horizontal`, which is just horribly wrong. I think that the compiler should never ever report an error on code that is not really there. What would happen if the programmer got a list of error and started fixing from the end? What if the guessed name was wrong? The programmer would spend time chasing some bug which doesn't exist outside of compiler's "that's what you probably meant" version of code.
I always fix the first 1 or 2 reported errors and try to recompile. I assume everyone did. A traditional "report on errors which are actually there each time they happen" compiler will give you tons of completely spurious errors which happily disappear once you fix the first few.
In the instance you point out, it could just uselessly say "no member named horisontal" but it knows it already gave you that error. So instead of repeating itself or shutting up, it reasons in the alternative--even if the name was corrected, the type is wrong. I would actually find that far more useful for fixing all the compiler errors at once.
[...] has type 'double' (assuming argument horizontal was intended)
With you on the reported errors and trying to recompile; more helpful error messages later in the build would remove some of those compile-fix-compile cycles.
As for turning it on or off, I've never had too, unless it's part of cindent.
On the other hand - if the recompile time is tiny, I don't bother with any specific order, I just fix what I see as trivial first. But when you see the clang's very verbose errors - how many can you fit on the screen? 10? 15? To make sure none of the last ones depend on some code guessing, you'd have to scroll to the top every time, instead of just fixing what you see.
I'm still not a fan of guessing - badly reported error is still better than properly reported error on a nonexisting code (potentially incorrectly guessed).
I've been bitten by the dependencies in C++ before. I have this file "image.h" which contains a templated image class with quite a few algorithms. My app is about image processing, so nearly everything uses the image datatype. I hate having to edit this file because it means recompiling nearly everything. Of course templates make it much worse than pure C...
For example, the C# compiler has a large number of passes, and it will do no more passes after seeing an a previous pass. Thus, you might knock a file down to one error, fix that error, and then find that you have a couple dozen more errors.
Indeed. Most annoyingly, many "modern" C compilers still attempt to muddle onward by replacing unknown types with "int".
I'm excited about clang but it's not that important: gcc is good enough. I'll just wait until I can install it from Ubuntu repositories, and then I'll happily try out and hopefully switch over to clang.
I've been using gcc for a while now, and every time I use it I found a new feature. It's rock solid and had never let me down.
Or do you use a lot of gcc extensions?
Those better warnings aren't just due to a simple UI patch ... clang is doing better and deeper static analysis than gcc in order to even be able to produce those more intelligent warnings.