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.

Post History

63%
+5 −2
Q&A Which functions in the C standard library must always be avoided?

Standard library functions that should never be used: setjmp.h setjmp() Together with longjmp(), these functions are widely recogniced as incredibly dangerous to use: they lead to spaghetti ...

posted 2y ago by Lundin‭  ·  edited 2y ago by Lundin‭

Answer
#3: Post edited by user avatar Lundin‭ · 2022-04-05T08:41:55Z (over 2 years ago)
  • **Standard library functions that should _never_ be used:**
  • ---
  • **setjmp.h**
  • - `setjmp()`
  • Together with `longjmp()`, these functions are widely recogniced as incredibly dangerous to use: they lead to spaghetti programming, they come with numerous forms of undefined behavior, they can cause unintended side-effects in the program environment, such as affecting values stored on the stack. References: MISRA-C:2012 rule 21.4, [CERT C MSC22-C](https://www.securecoding.cert.org/confluence/display/c/MSC22-C.+Use+the+setjmp(),+longjmp()+facility+securely).
  • - `longjmp()`
  • See `setjmp()`.
  • **stdio.h**
  • - `gets()`
  • The function has been removed from the C language (as per C11), as it was unsafe as per design. The function was already flagged as obsolete in C99. Use `fgets()` instead. References: ISO 9899:2011 K.3.5.4.1, also see note 404).
  • **stdlib.h**
  • - `atoi()` family of functions.
  • These have no error handling but invoke undefined behavior whenever errors occur. Completely superfluous functions that can be replaced with the `strtol()` family of functions. `strtol(src, NULL, 10)` is per definition 100% equivalent to `atoi` except with well-defined error handling. References: ISO 9899:2018 7.22.1.2, MISRA-C:2012 rule 21.7.
  • **string.h**
  • - `strncat()`
  • Has an awkward interface that are often misused. It is mostly a superfluous function. Also see remarks for `strncpy()`.
  • - `strncpy()`
  • The intention of this function was never to be a safer version of `strcpy()`. Its sole purpose was always to handle an ancient string format on Unix systems, and that it got included in the standard library is a known mistake. This function is dangerous because it may leave the string without null termination and programmers are known to often use it incorrectly. References: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518).
  • ---
  • **Standard library functions that should be used with caution:**
  • ---
  • **assert.h**
  • - `assert()`
  • Comes with overhead and should generally not be used in production code. In production code, it is better to use an application-specific error handler which displays errors but does not necessarily close down the whole program.
  • **ctype.h**
  • For all functions in this header, note this vulnerabilities listed by the C standard ISO 9899:2018:
  • > In all cases the argument is an `int`, the value of which shall be
  • representable as an unsigned char or shall equal the value of the macro `EOF`. If the argument has any other value, the behavior is undefined.
  • >
  • Therefore passing a `char` which possibly contains negative values to the ctype.h functions is dangerous practice.
  • **signal.h**
  • - `signal()`
  • Comes with various forms of poorly-defined behavior, particularly when called from within signal handlers.
  • References: MISRA-C:2012 rule 21.5, [CERT C SIG32-C](https://www.securecoding.cert.org/confluence/display/c/SIG34-C.+Do+not+call+signal%28%29+from+within+interruptible+signal+handlers).
  • **stdarg.h**
  • - `va_arg()` family of functions.
  • The presence of variable-length functions in a C program is almost always an indication of poor program design. Should be avoided unless you have very specific requirements.
  • **stdio.h**
  • Generally, _this whole library is not recommended for production code_, as it comes with numerous cases of poorly-defined behavior and poor type safety.
  • Yours sincerely likes to name this one the worst programming library ever designed for _any_ programming language, all categories, though of course that's subjective - I'm mostly basing this on monetary damage done to mankind.
  • - `fflush()`
  • Perfectly fine to use for output streams. Invokes undefined behavior if used for input streams.
  • - `gets_s()`
  • Safe version of `gets()` included in C11 bounds-checking interface. It is preferred to use `fgets()` instead, as per C standard recommendation. References: ISO 9899:2011 K.3.5.4.1.
  • - `printf()` family of functions.
  • Poor performance functions that come with lots of undefined behavior and poor type safety. `sprintf()` also has specific vulnerabilities. These functions should be avoided in production code. References: MISRA-C:2012 rule 21.6.
  • - `scanf()` family of functions.
  • See remarks about `printf()`. Also, - `scanf()` is vulnerable to buffer overruns if not used correctly. `fgets()` is preferred to use when possible. References: [CERT C INT05-C](https://www.securecoding.cert.org/confluence/display/c/INT05-C.+Do+not+use+input+functions+to+convert+character+data+if+they+cannot+handle+all+possible+inputs), MISRA-C:2012 rule 21.6.
  • - `tmpfile()` family of functions.
  • Comes with various vulnerability issues. References: [CERT C FIO21-C](https://www.securecoding.cert.org/confluence/display/CINT/FIO21-C.+Do+not+create+temporary+files+in+shared+directories).
  • - `feof()`
  • The use of loops such as `while(!feof(fp))` are almost certainly incorrect - instead the various file read functions used in the loop body should have their results checked directly.
  • - `ungetc()`
  • C17 7.31.11 Future language directions:
  • > The use of ungetc on a binary stream where the file position indicator is zero prior to the call is an obsolescent feature.
  • **stdlib.h**
  • - `malloc()` family of functions.
  • Perfectly fine to use in hosted systems, though be aware of well-known issues in C90 and therefore [don't cast the result](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). The `malloc()` family of functions should never be used in freestanding applications.
  • Also note that `realloc()` is dangerous in case you overwrite the old pointer with the result of `realloc()`. In case the function fails, you create a leak.
  • References: MISRA-C:2012 rule 21.3, [Why should I not use dynamic memory allocation in embedded systems?](https://electrical.codidact.com/posts/286121)
  • - `system()`
  • Comes with lots of overhead and although portable, it is often better to use system-specific API functions instead. Comes with various poorly-defined behavior. References: [CERT C ENV33-C](https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132).
  • **string.h**
  • - `strcat()`
  • See remarks for `strcpy()`.
  • - `strcpy()`
  • Perfectly fine to use, unless the size of the data to be copied is unknown or larger than the destination buffer. If no check of the incoming data size is done, there may be buffer overruns. Which is no fault of `strcpy()` itself, but of the calling application - that `strcpy()` is unsafe is mostly a myth created by Microsoft. References: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518)
  • - `strtok()`
  • Modifies the caller string and uses internal state variables, which could make it unsafe in a multi-threaded environment.
  • ---
  • This post was originally written by me [here](https://stackoverflow.com/a/46563868/584518). It has been updated here and with some links to Codidact content. I won't maintain the SO post any longer.
  • **Standard library functions that should _never_ be used:**
  • ---
  • **setjmp.h**
  • - `setjmp()`
  • Together with `longjmp()`, these functions are widely recogniced as incredibly dangerous to use: they lead to spaghetti programming, they come with numerous forms of undefined behavior, they can cause unintended side-effects in the program environment, such as affecting values stored on the stack. References: MISRA-C:2012 rule 21.4, [CERT C MSC22-C](https://www.securecoding.cert.org/confluence/display/c/MSC22-C.+Use+the+setjmp(),+longjmp()+facility+securely).
  • - `longjmp()`
  • See `setjmp()`.
  • **stdio.h**
  • - `gets()`
  • The function has been removed from the C language (as per C11), as it was unsafe as per design. The function was already flagged as obsolete in C99. Use `fgets()` instead. References: ISO 9899:2011 K.3.5.4.1, also see note 404).
  • **stdlib.h**
  • - `atoi()` family of functions.
  • These have no error handling but invoke undefined behavior whenever errors occur. Completely superfluous functions that can be replaced with the `strtol()` family of functions. `strtol(src, NULL, 10)` is per definition 100% equivalent to `atoi` except with well-defined error handling. References: ISO 9899:2018 7.22.1.2, MISRA-C:2012 rule 21.7.
  • **string.h**
  • - `strncat()`
  • Has an awkward interface that are often misused. It is mostly a superfluous function. Also see remarks for `strncpy()`.
  • - `strncpy()`
  • The intention of this function was never to be a safer version of `strcpy()`. Its sole purpose was always to handle an ancient string format on Unix systems, and that it got included in the standard library is a known mistake. This function is dangerous because it may leave the string without null termination and programmers are known to often use it incorrectly. References: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518)
  • ---
  • **Standard library functions that should be used with caution:**
  • ---
  • **assert.h**
  • - `assert()`
  • Comes with overhead and should generally not be used in production code. In production code, it is better to use an application-specific error handler which displays errors but does not necessarily close down the whole program.
  • **ctype.h**
  • - For all functions in this header, note this vulnerabilities listed by the C standard ISO 9899:2018:
  • > In all cases the argument is an `int`, the value of which shall be
  • representable as an unsigned char or shall equal the value of the macro `EOF`. If the argument has any other value, the behavior is undefined.
  • Therefore passing a `char` which possibly contains negative values to the ctype.h functions is dangerous practice.
  • **signal.h**
  • - `signal()`
  • Comes with various forms of poorly-defined behavior, particularly when called from within signal handlers.
  • References: MISRA-C:2012 rule 21.5, [CERT C SIG32-C](https://www.securecoding.cert.org/confluence/display/c/SIG34-C.+Do+not+call+signal%28%29+from+within+interruptible+signal+handlers).
  • **stdarg.h**
  • - `va_arg()` family of functions.
  • The presence of variable-length functions in a C program is almost always an indication of poor program design. Should be avoided unless you have very specific requirements.
  • **stdio.h**
  • - Generally, _this whole library is not recommended for production code_, as it comes with numerous cases of poorly-defined behavior and poor type safety. References: MISRA-C:2012 rule 21.6.
  • Yours sincerely likes to name this one the worst programming library ever designed for _any_ programming language, all categories, though of course that's subjective - I'm mostly basing this on monetary damage done to mankind.
  • - `fflush()`
  • Perfectly fine to use for output streams. Invokes undefined behavior if used for input streams.
  • - `gets_s()`
  • Safe version of `gets()` included in C11 bounds-checking interface. It is preferred to use `fgets()` instead, as per C standard recommendation. References: ISO 9899:2011 K.3.5.4.1.
  • - `printf()` family of functions.
  • Poor performance functions that come with lots of undefined behavior and poor type safety. `sprintf()` also has specific vulnerabilities. These functions should be avoided in production code. References: MISRA-C:2012 rule 21.6.
  • - `scanf()` family of functions.
  • See remarks about `printf()`. Also, - `scanf()` is vulnerable to buffer overruns if not used correctly. `fgets()` is preferred to use when possible. References: [CERT C INT05-C](https://www.securecoding.cert.org/confluence/display/c/INT05-C.+Do+not+use+input+functions+to+convert+character+data+if+they+cannot+handle+all+possible+inputs), MISRA-C:2012 rule 21.6.
  • - `tmpfile()` family of functions.
  • Comes with various vulnerability issues. References: [CERT C FIO21-C](https://www.securecoding.cert.org/confluence/display/CINT/FIO21-C.+Do+not+create+temporary+files+in+shared+directories).
  • - `feof()`
  • The use of loops such as `while(!feof(fp))` are almost certainly incorrect - instead the various file read functions used in the loop body should have their results checked directly.
  • - `ungetc()`
  • C17 7.31.11 Future language directions:
  • > The use of ungetc on a binary stream where the file position indicator is zero prior to the call is an obsolescent feature.
  • **stdlib.h**
  • - `malloc()` family of functions.
  • Perfectly fine to use in hosted systems, though be aware of well-known issues in C90 and therefore [don't cast the result](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). The `malloc()` family of functions should never be used in freestanding applications.
  • Also note that `realloc()` is dangerous in case you overwrite the old pointer with the result of `realloc()`. In case the function fails, you create a leak.
  • References: MISRA-C:2012 rule 21.3, [Why should I not use dynamic memory allocation in embedded systems?](https://electrical.codidact.com/posts/286121)
  • - `system()`
  • Comes with lots of overhead and although portable, it is often better to use system-specific API functions instead. Comes with various poorly-defined behavior. References: [CERT C ENV33-C](https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132).
  • **string.h**
  • - `strcat()`
  • See remarks for `strcpy()`.
  • - `strcpy()`
  • Perfectly fine to use, unless the size of the data to be copied is unknown or larger than the destination buffer. If no check of the incoming data size is done, there may be buffer overruns. Which is no fault of `strcpy()` itself, but of the calling application - that `strcpy()` is unsafe is mostly a myth created by Microsoft. References: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518)
  • - `strtok()`
  • Modifies the caller string and uses internal state variables, which could make it unsafe in a multi-threaded environment.
  • ---
  • This post was originally written by me [here](https://stackoverflow.com/a/46563868/584518). It has been updated here and with some links to Codidact content. I won't maintain the SO post any longer.
#2: Post edited by user avatar Lundin‭ · 2022-04-05T08:36:45Z (over 2 years ago)
  • **Standard library functions that should _never_ be used:**
  • ---
  • **setjmp.h**
  • - `setjmp()`
  • Together with `longjmp()`, these functions are widely recogniced as incredibly dangerous to use: they lead to spaghetti programming, they come with numerous forms of undefined behavior, they can cause unintended side-effects in the program environment, such as affecting values stored on the stack. References: MISRA-C:2012 rule 21.4, [CERT C MSC22-C](https://www.securecoding.cert.org/confluence/display/c/MSC22-C.+Use+the+setjmp(),+longjmp()+facility+securely).
  • - `longjmp()`
  • See `setjmp()`.
  • **stdio.h**
  • - `gets()`
  • The function has been removed from the C language (as per C11), as it was unsafe as per design. The function was already flagged as obsolete in C99. Use `fgets()` instead. References: ISO 9899:2011 K.3.5.4.1, also see note 404).
  • **stdlib.h**
  • - `atoi()` family of functions.
  • These have no error handling but invoke undefined behavior whenever errors occur. Completely superfluous functions that can be replaced with the `strtol()` family of functions. `strtol(src, NULL, 10)` is per definition 100% equivalent to `atoi` except with well-defined error handling. References: ISO 9899:2018 7.22.1.2, MISRA-C:2012 rule 21.7.
  • **string.h**
  • - `strncat()`
  • Has an awkward interface that are often misused. It is mostly a superfluous function. Also see remarks for `strncpy()`.
  • - `strncpy()`
  • The intention of this function was never to be a safer version of `strcpy()`. Its sole purpose was always to handle an ancient string format on Unix systems, and that it got included in the standard library is a known mistake. This function is dangerous because it may leave the string without null termination and programmers are known to often use it incorrectly. References: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518).
  • ---
  • **Standard library functions that should be used with caution:**
  • ---
  • **assert.h**
  • - `assert()`
  • Comes with overhead and should generally not be used in production code. In production code, it is better to use an application-specific error handler which displays errors but does not necessarily close down the whole program.
  • **signal.h**
  • - `signal()`
  • Comes with various forms of poorly-defined behavior, particularly when called from within signal handlers.
  • References: MISRA-C:2012 rule 21.5, [CERT C SIG32-C](https://www.securecoding.cert.org/confluence/display/c/SIG34-C.+Do+not+call+signal%28%29+from+within+interruptible+signal+handlers).
  • **stdarg.h**
  • - `va_arg()` family of functions.
  • The presence of variable-length functions in a C program is almost always an indication of poor program design. Should be avoided unless you have very specific requirements.
  • **stdio.h**
  • Generally, _this whole library is not recommended for production code_, as it comes with numerous cases of poorly-defined behavior and poor type safety.
  • Yours sincerely likes to name this one the worst programming library ever designed for _any_ programming language, all categories, though of course that's subjective - I'm mostly basing this on monetary damage done to mankind.
  • - `fflush()`
  • Perfectly fine to use for output streams. Invokes undefined behavior if used for input streams.
  • - `gets_s()`
  • Safe version of `gets()` included in C11 bounds-checking interface. It is preferred to use `fgets()` instead, as per C standard recommendation. References: ISO 9899:2011 K.3.5.4.1.
  • - `printf()` family of functions.
  • Poor performance functions that come with lots of undefined behavior and poor type safety. `sprintf()` also has specific vulnerabilities. These functions should be avoided in production code. References: MISRA-C:2012 rule 21.6.
  • - `scanf()` family of functions.
  • See remarks about `printf()`. Also, - `scanf()` is vulnerable to buffer overruns if not used correctly. `fgets()` is preferred to use when possible. References: [CERT C INT05-C](https://www.securecoding.cert.org/confluence/display/c/INT05-C.+Do+not+use+input+functions+to+convert+character+data+if+they+cannot+handle+all+possible+inputs), MISRA-C:2012 rule 21.6.
  • - `tmpfile()` family of functions.
  • Comes with various vulnerability issues. References: [CERT C FIO21-C](https://www.securecoding.cert.org/confluence/display/CINT/FIO21-C.+Do+not+create+temporary+files+in+shared+directories).
  • - `ungetc()`
  • C17 7.31.11 Future language directions:
  • > The use of ungetc on a binary stream where the file position indicator is zero prior to the call is an obsolescent feature.
  • **stdlib.h**
  • - `malloc()` family of functions.
  • Perfectly fine to use in hosted systems, though be aware of well-known issues in C90 and therefore [don't cast the result](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). The `malloc()` family of functions should never be used in freestanding applications.
  • Also note that `realloc()` is dangerous in case you overwrite the old pointer with the result of `realloc()`. In case the function fails, you create a leak.
  • References: MISRA-C:2012 rule 21.3, [Why should I not use dynamic memory allocation in embedded systems?](https://electrical.codidact.com/posts/286121)
  • - `system()`
  • Comes with lots of overhead and although portable, it is often better to use system-specific API functions instead. Comes with various poorly-defined behavior. References: [CERT C ENV33-C](https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132).
  • **string.h**
  • - `strcat()`
  • See remarks for `strcpy()`.
  • - `strcpy()`
  • Perfectly fine to use, unless the size of the data to be copied is unknown or larger than the destination buffer. If no check of the incoming data size is done, there may be buffer overruns. Which is no fault of `strcpy()` itself, but of the calling application - that `strcpy()` is unsafe is mostly a myth created by Microsoft. References: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518)
  • - `strtok()`
  • Modifies the caller string and uses internal state variables, which could make it unsafe in a multi-threaded environment.
  • ---
  • This post was originally written by me [here](https://stackoverflow.com/a/46563868/584518). It has been updated with some links to Codidact content.
  • **Standard library functions that should _never_ be used:**
  • ---
  • **setjmp.h**
  • - `setjmp()`
  • Together with `longjmp()`, these functions are widely recogniced as incredibly dangerous to use: they lead to spaghetti programming, they come with numerous forms of undefined behavior, they can cause unintended side-effects in the program environment, such as affecting values stored on the stack. References: MISRA-C:2012 rule 21.4, [CERT C MSC22-C](https://www.securecoding.cert.org/confluence/display/c/MSC22-C.+Use+the+setjmp(),+longjmp()+facility+securely).
  • - `longjmp()`
  • See `setjmp()`.
  • **stdio.h**
  • - `gets()`
  • The function has been removed from the C language (as per C11), as it was unsafe as per design. The function was already flagged as obsolete in C99. Use `fgets()` instead. References: ISO 9899:2011 K.3.5.4.1, also see note 404).
  • **stdlib.h**
  • - `atoi()` family of functions.
  • These have no error handling but invoke undefined behavior whenever errors occur. Completely superfluous functions that can be replaced with the `strtol()` family of functions. `strtol(src, NULL, 10)` is per definition 100% equivalent to `atoi` except with well-defined error handling. References: ISO 9899:2018 7.22.1.2, MISRA-C:2012 rule 21.7.
  • **string.h**
  • - `strncat()`
  • Has an awkward interface that are often misused. It is mostly a superfluous function. Also see remarks for `strncpy()`.
  • - `strncpy()`
  • The intention of this function was never to be a safer version of `strcpy()`. Its sole purpose was always to handle an ancient string format on Unix systems, and that it got included in the standard library is a known mistake. This function is dangerous because it may leave the string without null termination and programmers are known to often use it incorrectly. References: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518).
  • ---
  • **Standard library functions that should be used with caution:**
  • ---
  • **assert.h**
  • - `assert()`
  • Comes with overhead and should generally not be used in production code. In production code, it is better to use an application-specific error handler which displays errors but does not necessarily close down the whole program.
  • **ctype.h**
  • For all functions in this header, note this vulnerabilities listed by the C standard ISO 9899:2018:
  • > In all cases the argument is an `int`, the value of which shall be
  • representable as an unsigned char or shall equal the value of the macro `EOF`. If the argument has any other value, the behavior is undefined.
  • >
  • Therefore passing a `char` which possibly contains negative values to the ctype.h functions is dangerous practice.
  • **signal.h**
  • - `signal()`
  • Comes with various forms of poorly-defined behavior, particularly when called from within signal handlers.
  • References: MISRA-C:2012 rule 21.5, [CERT C SIG32-C](https://www.securecoding.cert.org/confluence/display/c/SIG34-C.+Do+not+call+signal%28%29+from+within+interruptible+signal+handlers).
  • **stdarg.h**
  • - `va_arg()` family of functions.
  • The presence of variable-length functions in a C program is almost always an indication of poor program design. Should be avoided unless you have very specific requirements.
  • **stdio.h**
  • Generally, _this whole library is not recommended for production code_, as it comes with numerous cases of poorly-defined behavior and poor type safety.
  • Yours sincerely likes to name this one the worst programming library ever designed for _any_ programming language, all categories, though of course that's subjective - I'm mostly basing this on monetary damage done to mankind.
  • - `fflush()`
  • Perfectly fine to use for output streams. Invokes undefined behavior if used for input streams.
  • - `gets_s()`
  • Safe version of `gets()` included in C11 bounds-checking interface. It is preferred to use `fgets()` instead, as per C standard recommendation. References: ISO 9899:2011 K.3.5.4.1.
  • - `printf()` family of functions.
  • Poor performance functions that come with lots of undefined behavior and poor type safety. `sprintf()` also has specific vulnerabilities. These functions should be avoided in production code. References: MISRA-C:2012 rule 21.6.
  • - `scanf()` family of functions.
  • See remarks about `printf()`. Also, - `scanf()` is vulnerable to buffer overruns if not used correctly. `fgets()` is preferred to use when possible. References: [CERT C INT05-C](https://www.securecoding.cert.org/confluence/display/c/INT05-C.+Do+not+use+input+functions+to+convert+character+data+if+they+cannot+handle+all+possible+inputs), MISRA-C:2012 rule 21.6.
  • - `tmpfile()` family of functions.
  • Comes with various vulnerability issues. References: [CERT C FIO21-C](https://www.securecoding.cert.org/confluence/display/CINT/FIO21-C.+Do+not+create+temporary+files+in+shared+directories).
  • - `feof()`
  • The use of loops such as `while(!feof(fp))` are almost certainly incorrect - instead the various file read functions used in the loop body should have their results checked directly.
  • - `ungetc()`
  • C17 7.31.11 Future language directions:
  • > The use of ungetc on a binary stream where the file position indicator is zero prior to the call is an obsolescent feature.
  • **stdlib.h**
  • - `malloc()` family of functions.
  • Perfectly fine to use in hosted systems, though be aware of well-known issues in C90 and therefore [don't cast the result](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). The `malloc()` family of functions should never be used in freestanding applications.
  • Also note that `realloc()` is dangerous in case you overwrite the old pointer with the result of `realloc()`. In case the function fails, you create a leak.
  • References: MISRA-C:2012 rule 21.3, [Why should I not use dynamic memory allocation in embedded systems?](https://electrical.codidact.com/posts/286121)
  • - `system()`
  • Comes with lots of overhead and although portable, it is often better to use system-specific API functions instead. Comes with various poorly-defined behavior. References: [CERT C ENV33-C](https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132).
  • **string.h**
  • - `strcat()`
  • See remarks for `strcpy()`.
  • - `strcpy()`
  • Perfectly fine to use, unless the size of the data to be copied is unknown or larger than the destination buffer. If no check of the incoming data size is done, there may be buffer overruns. Which is no fault of `strcpy()` itself, but of the calling application - that `strcpy()` is unsafe is mostly a myth created by Microsoft. References: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518)
  • - `strtok()`
  • Modifies the caller string and uses internal state variables, which could make it unsafe in a multi-threaded environment.
  • ---
  • This post was originally written by me [here](https://stackoverflow.com/a/46563868/584518). It has been updated here and with some links to Codidact content. I won't maintain the SO post any longer.
#1: Initial revision by user avatar Lundin‭ · 2022-04-05T08:28:57Z (over 2 years ago)
**Standard library functions that should _never_ be used:**
---

**setjmp.h**  

- `setjmp()`

  Together with `longjmp()`, these functions are widely recogniced as incredibly dangerous to use: they lead to spaghetti programming, they come with numerous forms of undefined behavior, they can cause unintended side-effects in the program environment, such as affecting values stored on the stack. References: MISRA-C:2012 rule 21.4, [CERT C MSC22-C](https://www.securecoding.cert.org/confluence/display/c/MSC22-C.+Use+the+setjmp(),+longjmp()+facility+securely).  
- `longjmp()`  
  See `setjmp()`.

**stdio.h**

- `gets()`  
  The function has been removed from the C language (as per C11), as it was unsafe as per design. The function was already flagged as obsolete in C99. Use `fgets()` instead. References: ISO 9899:2011 K.3.5.4.1, also see note 404).

**stdlib.h**  

- `atoi()` family of functions.  
  These have no error handling but invoke undefined behavior whenever errors occur. Completely superfluous functions that can be replaced with the `strtol()` family of functions. `strtol(src, NULL, 10)` is per definition 100% equivalent to `atoi` except with well-defined error handling. References: ISO 9899:2018 7.22.1.2, MISRA-C:2012 rule 21.7.

**string.h**

- `strncat()`   
  Has an awkward interface that are often misused. It is mostly a superfluous function. Also see remarks for `strncpy()`.
- `strncpy()`  
  The intention of this function was never to be a safer version of `strcpy()`. Its sole purpose was always to handle an ancient string format on Unix systems, and that it got included in the standard library is a known mistake. This function is dangerous because it may leave the string without null termination and programmers are known to often use it incorrectly. References: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518).

---

**Standard library functions that should be used with caution:**
---

**assert.h**  

- `assert()`  
   Comes with overhead and should generally not be used in production code. In production code, it is better to use an application-specific error handler which displays errors but does not necessarily close down the whole program.

**signal.h**  

- `signal()`  
   Comes with various forms of poorly-defined behavior, particularly when called from within signal handlers.

    References: MISRA-C:2012 rule 21.5, [CERT C SIG32-C](https://www.securecoding.cert.org/confluence/display/c/SIG34-C.+Do+not+call+signal%28%29+from+within+interruptible+signal+handlers).

**stdarg.h**

- `va_arg()` family of functions.  
   The presence of variable-length functions in a C program is almost always an indication of poor program design. Should be avoided unless you have very specific requirements.

**stdio.h**  
Generally, _this whole library is not recommended for production code_, as it comes with numerous cases of poorly-defined behavior and poor type safety.  
Yours sincerely likes to name this one the worst programming library ever designed for _any_ programming language, all categories, though of course that's subjective - I'm mostly basing this on monetary damage done to mankind.

- `fflush()`  
    Perfectly fine to use for output streams. Invokes undefined behavior if used for input streams.
- `gets_s()`  
    Safe version of `gets()` included in C11 bounds-checking interface. It is preferred to use `fgets()` instead, as per C standard recommendation. References: ISO 9899:2011 K.3.5.4.1.
- `printf()` family of functions.  
    Poor performance functions that come with lots of undefined behavior and poor type safety. `sprintf()` also has specific vulnerabilities. These functions should be avoided in production code. References: MISRA-C:2012 rule 21.6.  
- `scanf()` family of functions.  
   See remarks about `printf()`. Also, - `scanf()` is vulnerable to buffer overruns if not used correctly. `fgets()` is preferred to use when possible. References: [CERT C INT05-C](https://www.securecoding.cert.org/confluence/display/c/INT05-C.+Do+not+use+input+functions+to+convert+character+data+if+they+cannot+handle+all+possible+inputs), MISRA-C:2012 rule 21.6.  
- `tmpfile()` family of functions.  
    Comes with various vulnerability issues. References: [CERT C FIO21-C](https://www.securecoding.cert.org/confluence/display/CINT/FIO21-C.+Do+not+create+temporary+files+in+shared+directories).

- `ungetc()`  
   C17 7.31.11 Future language directions:

  > The use of ungetc on a binary stream where the file position indicator is zero prior to the call is an obsolescent feature.

**stdlib.h**  

- `malloc()` family of functions.  
    Perfectly fine to use in hosted systems, though be aware of well-known issues in C90 and therefore [don't cast the result](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). The `malloc()` family of functions should never be used in freestanding applications. 

  Also note that `realloc()` is dangerous in case you overwrite the old pointer with the result of `realloc()`. In case the function fails, you create a leak.

  References: MISRA-C:2012 rule 21.3, [Why should I not use dynamic memory allocation in embedded systems?](https://electrical.codidact.com/posts/286121)

- `system()`  
   Comes with lots of overhead and although portable, it is often better to use system-specific API functions instead. Comes with various poorly-defined behavior. References: [CERT C ENV33-C](https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=2130132).


**string.h**

- `strcat()`  
    See remarks for `strcpy()`.
- `strcpy()`  
   Perfectly fine to use, unless the size of the data to be copied is unknown or larger than the destination buffer. If no check of the incoming data size is done, there may be buffer overruns. Which is no fault of `strcpy()` itself, but of the calling application - that `strcpy()` is unsafe is mostly a myth created by Microsoft. References: [Is strcpy dangerous and what should be used instead?](https://software.codidact.com/posts/281518)
- `strtok()`  
    Modifies the caller string and uses internal state variables, which could make it unsafe in a multi-threaded environment.



---

This post was originally written by me [here](https://stackoverflow.com/a/46563868/584518). It has been updated with some links to Codidact content.