C programming Traps and Gotchas

Yes, but you may notice that your approach does exactly what I said, it requires parsing the entire expression before you can determine the proper operator precedence. Up through the eighties there was a lot of discussion among compiler creators about ways to short cut this process, because resources were limited and a complete parsing wasn’t always possible. By the eighties this problem was only showing up when the calculations were complex, but it still existed. Even today, many people rightly don’t trust the compiler to properly evaluate operator precedence. Now it is less to do with resource limitations and more to do with the fact that people with modern computer science degrees frequently have very poor math skills.

BTW, this is one reason I still love and use my HP15C, it is one of the few calculators where the math functions have actuallly been tested and proved (with a couple of minor exceptions) to actually produce the correct results.

RPN is hard for people to learn if they first learned algebraic method and are poor at math skills to begin with. Several generations of engineers learned it with little difficulty. While I love FORTH, it isn’t popular for more reasons then just RPN calculations. SInce it basically allows every programmer to create their own language, it was a nightmare for program maintenance…

I would hope that compilers evaluate expressions properly according to the language definition. People coding up their expressions properly is an entirely different issue.

All to often that isn’t the case. Fortunately, this usually doesn’t show up with typical calculations. But for anything complicated, it pays to read the eratta sheets in detail… And to use certified compilers.

Getting operator precedence wrong

Discussion:

C has many levels of operator precedence. Too many in my opinion.

There are a few which are just wrong. For example, to see whether the low order four bits of a value is six,

is wrong. The compiler treats that as

You have to write

Solution:

Use parenthesis if there is any doubt, but remember too many makes the code difficult to read.

Find a precedence table you like. (Print it or make a copy if it) and keep it handy.

…nonverbal pun there…

1 Like
4 Likes

array index starts with 0

Discussion:

When you declare an array

you have array[0], array[1] and array[2] available for use. An attempt to access array[3] is likely to be a problem.

1 Like

Pointer overruns with arrays and memory access

const int array_size=10;
int indx;
long some_array[array_size]'
long *array_ptr;

array_ptr = some_array
indx=0;

/* This will loop 11 times instead of 10, so on the last loop it will read something from memory 
and intepret as an long integer.  Even more of a problem is your writing to memory... */
while (indx <= array_size)  
{
 printf("*(ptr %d) = %ld\n", indx, *(array_ptr + indx));
 indx++;
}

The above SHOULD be either

const int array_size=10;
int indx;
long some_array[array_size]'
long *array_ptr;

array_ptr = some_array
indx=0;

while (indx < array_size)  
{
 printf("*(ptr %d) = %ld\n", indx, *(array_ptr + indx));
 indx++;
}

or

const int array_size=10;
int indx;
long some_array[array_size]'
long *array_ptr;

array_ptr = some_array
indx=0;

while (indx <= (array_size-1))  
{
 printf("*(ptr %d) = %ld\n", indx, *(array_ptr + indx));
 indx++;
}
1 Like

Two comments;

  1. For someone aware array indices start with zero,

is much clearer than

  1. This is some convoluted code. Why have a pointer at all unless you are incrementing it instead of indexing into it?
const int array_size=10;
int indx;
long some_array[array_size];
indx=0;
while (indx < array_size)  
	{
	printf("*(ptr %d) = %ld\n", indx, some_array[indx]);
	indx++;
	}

Yes convoluted, but the quickest example I could think of to cover pointer over runs in an area that would be clear to most. Didn’t want to use malloc…

1 Like

Extraneous semicolon in the wrong place

Example:

	if (value);

or

	while (value);

Discussion:

C requires a semicolon at the end of each statement. It is easy to get into the habit of typing a semicolon after a closing parenthesis, especially when it resembles a function call. In most places, it is harmless or you get a syntax error. But after an if or a while, your code does unexpected things.

hideous death by side effect

Examples:

function(i++, i++);

bigger = MAX(*a++, *b++);

Discussion:

In the first example, the order of evaluation is not defined. All we know is that one is one bigger than the other and i is two bigger than it started.

In the second example, MAX is often a macro defined as:

#define MAX(a,b) (((a)>(b))?(a):(b))

so the expansion is ((( *a++)>( *b++))?( *a++) : ( *b++))

Probably not what anyone wanted.

1 Like