C C Compiler

Hey guys. I am wondering, which compiler do you guys like to use?

My cc looks like clang bsd, and I dont know if I had set as that or it is the OS default.
I have seen some people saying that clang is slow and bloat, so I would like to know if there is a favorite among ones here.

Also, there is an CC bin, but some applications that I try to use sometimes cant find it if there isnt an CC shell variable set as default.

So, if CC env value matters more than the cc on /usr/bin/cc, what is the point of having such binarie?
Also, how could I change this binarie to other compiler if I want to?
Delete cc and create a symlink from other one? or just keep using shell envs?
 
I have seen some people saying that clang is slow and bloat, so I would like to know if there is a favorite among ones here.
Most modern C and C++ compilers are quite bloated.

Its actually amazing how heavy, complex, unportable and messy we have made a tool which has almost zero dependencies outside of the standard C library. It reads file(s) and outputs file(s); it doesn't even need to access the operating system in any other way.

So, if CC env value matters more than the cc on /usr/bin/cc, what is the point of having such binarie?
POSIX / SUS pretty much dictates it.
Plus, sometimes CC env isn't set so defaulting to the system cc is the only sane choice left.
 
Hey guys. I am wondering, which compiler do you guys like to use?
Whatever the target OS provides. IMHO, you really shouldn't care. Using a specific compiler is for very special situations where you can profit a lot from some specific compiler extension(s). And sometimes it's a necessity to work around broken code (containing undefined or implementation-defined behavior) that is known to compile to a broken/crashing mess when not using "frobcc-4.3+2004_svn_beta1", IOW, by all means avoid running into that. The default approach should be to write standard-compliant and correct code that works with every standard-compliant and correct compiler.

My cc looks like clang bsd, and I dont know if I had set as that or it is the OS default.
It's the default. It's used to build FreeBSD and is part of base.

I have seen some people saying that clang is slow and bloat, so I would like to know if there is a favorite among ones here.
I don't know. I've seen GCC show more helpful warnings sometimes recently, but that could have been coincidence. I'm perfectly fine with LLVM/clang.

Also, there is an CC bin, but some applications that I try to use sometimes cant find it instead there is an CC shell variable set as default.
CC is not set by default. It's the canonic way to override what C compiler to use. A sane build system should always prefer cc as found in the default PATH, unless CC is set to something different.

So, if CC env value matters more than the cc on /usr/bin/cc, what is the point of having such binarie?
User override, see above. It's btw a hardlink on FreeBSD to clang.

Also, how could I change this binarie to other compiler if I want to?
You don't. You pass CC to the build system of whatever you want to compile with a different compiler. If the build system gets that wrong, complain to its authors, it's broken.

Sure you could just put something different in /usr/bin/cc, but that's certainly begging for trouble. Sometimes, it's actually important that the system's default compiler is used. That's even more important when talking about C++ (canonic name c++), because there's no defined ABI for C++ libraries, so a binary built with one compiler is somewhat likely to be incompatible with a library built with a different one.
 
If you want a different compiler to build a stubborn thing that doesn't obey to $CC then create a new directory tree in e.g. ~/usr and put a script in ~/bin/bin/cc that invokes the compiler you want. Then put that first in $PATH for the duration of that compilation.
 
There are a bunch of alternate C compilers, each with their differences. tinycc and cproc are significantly faster at compiling and a tiny fraction of the size of clang/gcc and they use far fewer resources. The generated code will typically be slower -- which should not matter much while you're developing your code. You can then compile with clang/gcc for "production" use. But you should be aware of their differences and limitations.

You should leave the system C compiler alone - don't delete it as that could break things. If you are using one of make, cmake, meson etc. make like tools, you can simply choose the compiler of your choice by setting CC env. var. or passing it in command line, or use a script called cc.

A number of choices are possible. What makes sense depends on your goals.
 
tinycc and cproc are significantly faster at compiling and a tiny fraction of the size of clang/gcc and they use far fewer resources. The generated code will typically be slower -- which should not matter much while you're developing your code. You can then compile with clang/gcc for "production" use.
That's an interesting aspect. I'd like to present a reason why you might not want to do this though: Part of what makes modern compilers (GCC and clang in the opensource world) so "bloated" is their very complex and sophisticated optimization and diagnostics features (which are often somewhat correlated). Getting good warnings from the compiler is very helpful to avoid broken code in C (and C++). And building fully optimized is a good way to actually break the binary when there's some UB hidden in your code, while a simpler compiler might build something that happens to "work" nevertheless (so, you'll get a nasty surprise only when you build for your "release" ...)

BTW, I'd suggest to always build with -std=c11 -Wall -Wextra -pedantic (the c11 is an example of course, but do specify the C standard version you intend to use, it enables even better warnings in some cases). For a "CI" or dev/debug build, also add -Werror (but make sure to remove it for production, it's a "nice" way to needlessly break builds with future compiler versions happening to add some warning that happens to be not too relevant for your code otherwise).

edit: This recommendation about enabling warnings reminds me of one thing I really disliked about GCC: This compiler can issue some warnings only with optimizations (at least -O2) enabled. So, add this for a "CI" build as well when using GCC. As I said, optimization and diagnostics are somewhat correlated, need similar analysis steps, but still I think this GCC behavior isn't a sign of "good design" ... they should have found a better way to reuse some code than requiring the user to enable optimizations for getting all warnings 🧐
 
You may have to use things like CI when you are writing code as part of a team (and of course everyone in the team should be using the same toolchain). For a solo developer that matters much less than a quick edit-compile-test cycle. You can periodically run with all warnings turned on to cleanup code but relying on the compiler all the time is not necessary: understand & internalize the language semantics. Play with sample code to get a better feel for language corners. And avoid tricky code in the name of "optimization". And if you must, make sure the algorithm is fully documented (or give a link to the underlying algo). There are very clever algorithms for all sorts of things but use them only if they are worth it (for the target uses of your programs). Having to rely on heavyweight tools and complicated optimizations is sort of like saying you must have well built roads and well supplied workers to advance. That may be fine if you are taking over enemy's territory or building something that should last a long time. But it is the wrong thing if all you are doing is exploring something. Then you hack through the jungle and find a new path or destination! You may not even be sure of what you may find so don't waste time building permanent roads for tanks.
 
Thats interesting. Is it related to strict aliasing?
Unfortunately, I don't remember where exactly I ran into this, I only remember it was during setup of some "workflow" on github for a CI build which I wanted to test with a deliberate error and it turned green...

So I checked the GCC warning docs again, but still can't remember. But, have a look there for "fun". Seems my claim "at least -O2" was over-simplified....

bakul I don't know your experience with C. Maybe you do nothing else your whole (work) day. You'd still be the first example to me of someone who always avoids every single possible pitfall for UB or similar. I'm using C a lot, enough to claim I "fully" know the language, and still I can't avoid running into some compiler warning from time to time, with a certain fraction of them indeed indicating bugs (of course I also "fix" the irrelevant ones, you need a clean build log for new warnings to be useful). To me, a CI build is very useful even when working alone. My typical scenario is a dev environment on FreeBSD using clang, while the CI build is running via Github's "workflows" on Ubuntu, using GCC. The environments differ enough to run into different issues, and of course the compilers have different warnings, seeing both of them covers more. And of course warnings are no "silver bullet" (and certainly won't help you if you just code crap). I recently had to fix a bug where I forgot casting characters to unsigned char to use them with the ctype.h APIs. No warnings about that, but interestingly, NetBSD has some trickery in its standard headers to force a warning about that ... seems it happens often enough.
 
Back
Top