Saturday, March 20, 2010

Uninitialized variable in s-function = Misery

Let's prepare the following Simulink model:

The underlying s-function is as follows:

I configured MATLAB to use the lcc compiler by running mex -setup. Note that the variable limitNb on line 160 is not initalized (it should be, because it is input into the limit function). If I run the Simulink model I get the following output:

The printf commands have printed zero, but the Display block in the model seems to be more accurate by saying that the result is 3.358e-323. That number is a clear indication that there is an initialization error. Nothing very interesting here. But let's comment out the printf on line 164. I would not expect the ouput to change because printf does not change the value of variables, right? Not so in case of uninitiazed ones it looks:

Hmm... Let's comment out another printf, the one on line 162 and run the model. Again, the output changes:

Finally, let's change the compiler to Visual Studio 2003 by mex -setup and then rerun our model. The results change again, and worse, there is no indication that something is wrong:

Moral of the story: If you forget to initialize a variable and try to find the bug by using printf's, you are in for misery.

The best way to detect such bugs is to put the algorithm in your s-function in a separate header/c file and include that in the s-function. Then you can use a more responsive compiler to check the header file. A good compiler can detect unitialized variables at compile time and warn you. For example, if I separate the algorithm, put it into myAlgorithm.h and make a VS2003 project, I get the following warning when I compile:
myalgorithm.h(5) : warning C4700: local variable 'limitNb' used without having been initialized
Using static code analysis tools is also advised. Finally, do code reviews for God's sake!

Further reading: (pdf) C Traps and Pitfalls

No comments: