According to the clang home page as of March 7th 2010, "Clang's C++ support is currently alpha quality at best, but is evolving rapidly."
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.
The clang developers fully intend to support C++. It's just a more complex language, and as an Apple-supported project, C and Obj-C were higher priorities. clang itself is written in C++ and is self-hosting. I expect that by the end of next year, it will be able to handle Boost and any other reasonable C++ code.
One day I discovered that I'd hand-coded a vtable in order to allow polymorphism in structures of function pointers.
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.)
Why not make it easier if you can? Vagueness is hardly a virtue for a programming tool. Also, I don't think the ladies are impressed by your cryptic error fixing skills ;)
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.
What this feature needs now is code correction on the fly
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
That semicolon-omitted-after-struct error used to happen to me irregularly but frequently enough to really piss me off. It's annoying precisely because it's nonlocal and it interacts badly with the C preprocessor model.
I wouldn't hold out for any miracles. I think that there are several aspects of the language itself that will make improving error messages difficult. In particular, template error messages are probably without much hope.
I can think of one example, heavy use of macros can create a syntax error nightmare. One of the projects I've worked on (I had inherited it without documentation) had some seriously obtuse nested macros that threw a spanner in the works at least once.
It's better not to use macros. Let the compiler optimize. If you really need more control use __inline. Debugging code generated from complex macros is close to impossible.
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.
That's a good exception to the rule, but you have to admit it's not common.
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 it's a matter of taste, and I just look at C-style macros as a means to an end.
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.
I am currently switching between gcc and clang for my codebase. The performance is mixed. For some programs (2-level hashtable, for example), the clang version got about 50% speed up against gcc and icc. But other programs (sobel filter for example), clang version slows down about 25% (against gcc 4.4). The result certainly machine specific, but I think clang can do better in a long run.
Although cryptic, I'd say that gcc's error messages are manageable. I'd hold other factors, such as performance of compiled code - across platforms - to be more important. Alternatively, they could improve on the C++ template error reporting (when they get around to taking C++ support beyond alpha) and that may be enough to sell me.
If clang could come up with better C++ template error messages that would be really sweet. STL related error messages in g++ (and MSVC) are really hard to figure out, especially when C++ is not your main language; so you're not exposed to those problems on a daily basis.
As a dynamic language guy, I can't help but look at the static analysis here and feel a twinge of jealousy. There really isn't anything like this in the Ruby world.
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.
I spend most of my time writing C code, but like to work with Python when I get the chance. There isn't anything like pylint for Ruby? A dynamic runtime doesn't necessarily mean you have to give up static analysis.
roody, rufus, reek, flay, flog, probably more. Sadly, in the current state of the ruby community it's even hard to find a library that will run with ruby's own warnings enabled.
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.
clean code, yes, but some of the warnings are actually generated in situations where the code won't be cleaner (e.g. lazy initializing an instance variable not declared in the initialization method) and since quite a lot of the most common libraries have _a lot_ of warnings, it becomes unlikely that you will have them enabled in your app, and so the thing self propagates
An even better reason to use clang: it supports Apple's new syntax for blocks. I'm trying to think of a new project to write in C now just to take advantage of the simple anonymous functions and closures that are possible.
Proprietary extensions are one reason that gcc is so hard to unseat. You're always better off writing standard code if you want it to work in ten years.
Hardly proprietary. Apple gave the "block" patches to the gcc team. Gcc isn't interested in them, they are holding off for some future C++ syntax, though I don't see how that helps C programmers.
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.)
"Gcc isn't interested in them, they are holding off for some future C++ syntax, though I don't see how that helps C programmers."
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.
Closures in C make me uncomfortable, but lexically scope subfunctions are just syntax that serve two functions for me.
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.
Yes, nonstandard. I apologize for my sloppy wording.
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.
Now, now. LLVM and clang are very interesting projects but changing compilers just because of one feature isn't smart. GCC is good enough in that area and the code it generates is amazing, it often beats every other C compiler out there. And that helps keeping readable code optimized.
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."
Part of being a C developer (or C++ template) developer is in fact understanding what the compiler spits out. So, this did't convine me enough because "two or more data types" made me skip right a head to the definition of Point. :-)
My point is Clang is good but friendly error messages is not the only reason I would change to Clang.
Would you be interested in a compiler where the error messages are more difficult to decipher, then? That way you could feel even more like you're a developer.
I'm not sure this screenshot is convincing. Do you see the last error message?
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.
"What would happen if the programmer got a list of error and started fixing from the end?"
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.
I usually try to fix as many errors as I can identify before recompiling. And yes, I usually fix from the bottom up, because that way my changes don't alter the line numbers of future fixes. On large projects, recompile time can be significant.
Yes, sure, large projects can take time to compile, but doesn't your compile environment just try to recompile the last file that it failed on during the build? That is, if in trying to build my app FooBar, and foo.c compiles ok but bar.c fails, when I try to run the build the next time having modified bar.c, it starts by trying to compile bar.c anyway... So I guess what I'm trying to say is that I don't understand the advantage you are apparently getting by woring from bottom up.
I don't want to get into the specifics of the build system since it's proprietary, but there's a non-trivial startup cost for it. It's optimized for being able to compile really huge projects in a tractable amount of time, not being able to recompile individual files in the shortest possible amount of time. The latter will execute quickly enough (yes, it only recompiles what you've changed), but the startup time is still annoying enough to want to batch up edits.
If you are using :make, and _don't_ jump out of the file (split the window if you need to jump out), line deletions and additions down the window are automatically accounted for.
As for turning it on or off, I've never had too, unless it's part of cindent.
Use the :make command so that vim knows about the errors. Then use :clist to list errors, :cnext to go to the next error, etc. :help clist and :help make will get you started.
I agree, but it might be helpful if it put something in saying that it had made that assumption. For example they could say
[...] 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.
One point was mentioned - recompiling time may be huge.
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).
How long is recompiling really going to be if it's one file, though? I'm not talking about C++, which clang isn't quite fluent in yet, but one file of pure C shouldn't take long to compile. Or have I not been compiling the right C files?
Let's say you edit point.h, and many files include it. Then these files must be compiled too, and the files that include them, etc. until eventually you compile nearly the whole application.
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...
It's quite common and accepted for compilers to make assumptions about the rest of the code, and for those to be wrong if your code is broken.
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.
the struct point holds a def for the correct spelling so I would guess that they are using known good variables and suggests the one that is closest to it.
You don't have to convince me — you have to convene me.
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.
That is pretty impressive. I use colorgcc to make gcc's messages easier to spot and sort, and I always thought gcc had the best error messages (better than MSVC last time I tried it). I might just try clang to see if its messages are better in all the cases I typically encounter.
It's intuitive and shows new-world thinking. Most gcc developers are too old to care about doing such enhancements to gcc. They wouldn't change it just for the sake of status quo. As of 2010 we do need stuff like this, though gcc still has enough many traits not to switch to another compiler.
you're saying I should port all my code just because the ui is more user-friendly? what about performance, options, special warnings, builtins, and everything else?
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.
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.
Doesn't dehydra do static analysis for C++ code? In which case, of course it would do better then clang; clang doesn't even claim to have complete c++ support yet.
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.