\section{Logic and Program flow mistakes}

These are a set of mistakes that may let the program compile but perform unintended functionality.

\subsection{Equal vs. Equality}

Confusingly in C, the assignment operator also returns the assigned value.
Most of the time it is ignored.
We can use it to initialize multiple things on the same line.

\begin{lstlisting}[language=C]
int p1, p2;
p1 = p2 = 0;
\end{lstlisting}

More confusingly, if we forget an equals sign in the equality operator we will end up assigning that variable.
Most of the time this isn't what we want to do.

\begin{lstlisting}[language=C]
int answer = 3; // Will print out the answer.
if (answer = 42) { printf("The answer is %d", answer);}
\end{lstlisting}

The quick way to fix that is to get in the habit of putting constants first.
This mistake is common enough in while loop conditions.
Most modern compilers disallows assigning variables a condition without parenthesis.

\begin{lstlisting}[language=C]
  if (42 = answer) { printf("The answer is %d", answer);}
\end{lstlisting}

There are cases where we want to do it.
A common example is getline.

\begin{lstlisting}[language=C]
while ((nread = getline(&line, &len, stream)) != -1)
\end{lstlisting}

This piece of code calls getline, and assigns the return value or the number of bytes read to nread.
It also in the same line checks if that value is -1 and if so terminates the loop.
It is always good practice to put parentheses around any assignment condition.

\subsection{Undeclared or incorrectly prototyped functions}

Some snippets of code may do the following.

\begin{lstlisting}[language=C]
time_t start = time();
\end{lstlisting}

The system function `time' actually takes a parameter a pointer to some memory that can receive the time\_t structure or NULL.
The compiler fails to catch this error because the programmer omitted the valid function prototype by including \keyword{time.h}.

More confusingly this could compile, work for decades and then crash.
The reason for that is that time would be found at link time, not compile-time in the C standard library which almost surely is already in memory.
Since a parameter isn't being passed, we are hoping the arguments on the stack (any garbage) is zeroed out because if it isn't, time will try to write the result of the function to that garbage which will cause the program to SEGFAULT.

\subsection{Extra Semicolons}

This is a pretty simple one, don't put semicolons when unneeded.

\begin{lstlisting}[language=C]
for(int i = 0; i < 5; i++) ; printf("Printed once");
while(x < 10); x++ ; // X is never incremented
\end{lstlisting}

However, the following code is perfectly OK.

\begin{lstlisting}[language=C]
for(int i = 0; i < 5; i++){
  printf("%d\n", i);;;;;;;;;;;;;
}
\end{lstlisting}

It is OK to have this kind of code because the C language uses semicolons (;) to separate statements.
If there is no statement in between semicolons, then there is nothing to do and the compiler moves on to the next statement
To save a lot of confusion, \textbf{always use braces.}
It increases the number of lines of code, which is a great productivity metric.


