(Updated November 24, 2021)
Overview
This section is a collection of some of the well-known undefined behaviors. This is not an exhaustive list and is intended to provide the learner with situations they may encounter when programming in C.
The ISO/IEC 9899:2018 standard states undefined behavior through the document. The purpose of this is to allow compiler designers flexibility on how such situations are handled including ignoring them outright.
Flushing stdin
In some texts when trying to handle odd combinations of user input there is a recommendation to do the following:
fflush(stdin);
The thought is that the input stream buffer will be emptied. In Chapter 3, we expressly state that mixing forms of reading user input is not recommended and can lead to undefined behavior. For example, when trying to read a string with fgets()
after having read a number with scanf()
. The string cannot be read since the newline remains unconsumed in the input buffer and subsequently tricks fgets()
into thinking the input has been satisfied. So, people try to “fix” it like this:
printf("Enter a number: ");
scanf("%d", &i);
printf("You entered %d.\n", i);
fflush(stdin); // UB!
printf("Enter your name: ");
fgets(s, sizeof(s), stdin);
printf("You entered \"%s\".\n", s);
Undefined behavior using fflush()
.
The issue we are trying to resolve is the example output below.
Enter a number: 5 You entered 5. Enter your name: You entered " ".
We can see that the call to fgets() actually does happen. It consumes the newline and realizes it is now done and returns the newline as part of the input, hence the odd output.
While the above code seems like a good idea to remedy the situation, the official C standard expressly states this to be undefined behavior. While the POSIX standard does seem to extend the behavior of fflush()
and many Linux flavors expressly say (in their man pages) this will clear the input buffer, it cannot be relied on.