Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Comments on What compiler options are recommended for beginners learning C?
Parent
What compiler options are recommended for beginners learning C?
When reading questions about C programming from beginners, I very often see them describing peculiar run-time errors and crashes, segmentation faults and similar. They have spent a lot of time chasing down the bug but failed.
Then upon viewing their code, I notice that the code should never have "compiled cleanly" - there were warnings, but the beginner didn't read them. If they had done so, it would have saved them a lot of time.
Not reading warnings could in turn be caused by the IDE used, which is hiding away warnings in some hard-to-spot window, or because they picked some "compile & run" option, or simply because they weren't paying attention.
Or possibly because they think that warnings mean "here's a little cosmetic issue that you should fix when you have time", and not "here is a severe bug that will likely prevent your program from working as expected" which is closer to the truth most of the time.
Unfortunately, a compiler isn't required to give an error upon C language violations. A "diagnostic message" is sufficient, as discussed at What must a C compiler do when it finds an error?
Are there any recommended compiler options beginners should use to avoid accidentally running programs with errors already spotted by the compiler?
Mostly interested in the "gcc-like" mainstream compilers: gcc, clang and icc, which have compatible command-line options.
Post
The following users marked this post as Works for me:
User | Comment | Date |
---|---|---|
Lover of Structure | (no comment) | Jul 18, 2023 at 12:44 |
Lundin | (no comment) | Aug 7, 2023 at 09:21 |
My recommended beginner setup for gcc-like compilers is:
-std=c11 -pedantic-errors -Wall -Wextra -Werror
Here is an explanation of what these options do:
-
-std=c11
. gcc & friends are by default set to include non-standard language extensions. These extensions are known as "GNU C" and extensively used in Linux programming in particular.However, when learning the language it is important to know what parts that are standard C and what parts that are non-portable compiler extensions. Beginners should focus on learning the C language as specified by the standard ISO 9899, before they move on to learn about various extensions and libraries.
-std=c11
changes the compiler from using the default "GNU 11" to only use the features specified by the C language standard (ISO 9899:2011).There is a newer version of the language called "C17/C18", gcc and clang support it, but icc does not (yet). The differences between C17 and C11 are various detailed, advanced error fixes and nothing that concerns beginners. If you are using gcc or clang, you may as well use
-std=c17
though. -
-pedantic-errors
. Together with the-std=c...
option above, this forces the compiler into a strict mode. It doesn't mean "whine and be pedantic" as the name implies, but rather "give me diagnostic messages whenever I write invalid C". So this is the most "correct" mode to use when you want to see if your code is valid C or not.There's an option
-pedantic
that gives warnings for invalid C.-pedantic-errors
is the same but gives errors and prevents the code from compiling. -
-Wall
doesn't mean "enable all warnings" as one might suspect. It rather means "give me some more warnings that are good to have". -
-Wextra
adds some more warnings still. -
-Werror
turns all warnings into errors and prevents the code from executing until the problems are fixed.
Some other options that may be helpful:
-
-O3
vs-O0
. Enable or disable compiler optimizations. If you are concerned about program performance, then you need to use-O3
to enable all optimizations. This might be problematic when you are debugging/troubleshooting though, it's generally recommended to turn optimizations off when debugging. That is done with-O0
. -
-Wunused_result
. This warns if you don't check the returned result from a function. Very handy to have but note that this one might get spammy, because most library functions that we commonly use (printf
,scanf
,strcpy
etc) do return a result, which we aren't always interested in. You can cast the result of a function to(void)
in case you aren't interested in it - that's good practice, but writing(void)
in front of every single printf call might get tedious. -
-ffreestanding
. Always use this if you are compiling for an embedded system, such as a microcontroller application. -
-fno-strict-aliasing
is also strongly recommended for embedded systems, but that's a more advanced topic that I won't address here since this answer is aimed to beginners. (This option might only have an effect on gcc, I believe clang ignores it.)
Do not use:
-
-ansi
. There's a common misunderstanding that this enables strict C compilation. It does not, that's-std=c11 -pedantic-errors
as explained above.-ansi
enables "ANSI C", which is the nickname of the old, obsolete C90 standard, which should be avoided since it comes with a lot of language flaws that have been corrected over the years.
0 comment threads