Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

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?

+12
−0

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.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

Post
+13
−0

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.
History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

3 comment threads

Is -Wunused-result already enabled by default? (1 comment)
-ansi (3 comments)
Reason for -ansi misunderstanding (1 comment)
-ansi
Canina‭ wrote over 3 years ago

https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html even specifies for -ansi that "In C mode, this is equivalent to -std=c90. In C++ mode, it is equivalent to -std=c++98." Unless you're compiling code that is 20-30 years old by now, that's almost certainly not what you want. And in the unlikely case that it actually is what you want, then typing out the few extra characters required for -std= instead helps to clarify intent.

Martin Bonner‭ wrote about 3 years ago

"Unless you're compiling code that is 20-30 years old by now" - you say that like it is unlikely. Some of the code in my employers codebase was checked in more than 20 years ago. It gets compiled every time I do a build. (I believe we have moved on to at least C99).

Lundin‭ wrote about 3 years ago

Martin Bonner‭ The context of this post is how beginners should compile their programs. They should most definitely not be compiling code that old. In case of professionals, we all have our cross to bear in the form of maintaining old, bade code. I'm still maintaining some (naive) old code written by myself 18 years back, in C90. Add heavy code rot over the years... it ain't pretty.