Update
This commit is contained in:
parent
74cc61fae6
commit
ed28560132
15 changed files with 1738 additions and 1693 deletions
|
@ -2,6 +2,8 @@
|
|||
|
||||
[C](c.md) is a powerful language that offers almost absolute control and maximum performance which necessarily comes with responsibility and danger of shooting oneself in the foot. Without knowledge of the pitfalls you may well find yourself fallen into one of them.
|
||||
|
||||
This article will be focused on C specific/typical pitfalls, but of course C also comes with general [programming](programming.md) pitfalls, such as those related to [floating point](float.md), [concurrency](concurrency.md), bugs such as [off by one](off_by_one.md) and so on -- indeed, be aware of these ones too.
|
||||
|
||||
Unless specified otherwise, this article supposes the C99 standard of the C language.
|
||||
|
||||
**Generally**: be sure to check your programs with tools such as [valgrind](valgrind.md), [splint](splint.md), [cppcheck](cppcheck.md), UBSan or ASan, and turn on compiler auto checks (`-Wall`, `-Wextra`, `-pedantic`, ...), it's quick, simple and reveals many bugs!
|
||||
|
@ -48,6 +50,10 @@ int main(void)
|
|||
|
||||
Besides being extra careful about writing memory safe code, one needs to also know that **some functions of the standard library are memory unsafe**. This is regarding mainly string functions such as `strcpy` or `strlen` which do not check the string boundaries (i.e. they rely on not being passed a string that's not zero terminated and so can potentially touch memory anywhere beyond); safer alternatives are available, they have an `n` added in the name (`strncpy`, `strnlen`, ...) and allow specifying a length limit.
|
||||
|
||||
**Be careful with [pointers](pointer.md)**, pointers are hard and prone to errors, use them wisely and sparingly, assign NULLs to freed pointers and so on and so forth.
|
||||
|
||||
**Watch out for [memory leaks](memory_leak.md)**, try to avoid dynamic allocation (static/automatic allocation mostly suffices) and if you have to use it, simplify it as much as you can and additionally double and triple check everything (manually as well as with tools like [valgrind](valgrind.md)).
|
||||
|
||||
## Different Behavior Between C And C++ (And Different C Standards)
|
||||
|
||||
C is **not** a subset of C++, i.e. not every C program is a C++ program (for simple example imagine a C program in which we use the word `class` as an identifier: it is a valid C program but not a C++ program). Furthermore a C program that is at the same time also a C++ program may behave differently when compiled as C vs C++, i.e. there may be a [semantic](semantics.md) difference. Of course, all of this may also apply between different standards of C, not just between C and C++.
|
||||
|
@ -109,5 +115,7 @@ Of course this applies to other languages as well, but C is especially known for
|
|||
## Other
|
||||
|
||||
Watch out for **operator precedence**! Bracket expressions if unsure, or just to increase readability for others.
|
||||
|
||||
**[Preprocessor](preprocessor.md) can give you headaches** if you use it in overcomplicated ways -- ifdefs and macros are fine, but too many nesting can create real mess that's super hard to debug. It can also quite greatly slow down compilation. Try to keep the preprocessing code simple and flat.
|
||||
|
||||
Also watch out for this one: `!=` is not `=!` :) I.e. `if (x != 4)` and `if (x =! 4)` are two different things, the first means *not equal* and is usually what you want, the latter is two operations, `=` and `!`, the tricky thing is it also compiles and may work as expected in some cases but fail in others, leading to a very nasty bug.
|
Loading…
Add table
Add a link
Reference in a new issue