Tuesday, June 21, 2022

Stop build when "C4013 ... undefined; assuming extern returning int"

Recently I had to deal with a bug in a C project whose root cause was fabs not functioning properly due to missing #include <math>. Finding the root cause involved diving into more than 4 layers of abstractions, it was not fun (!) When run from Visual Studio as a dll project, the code resulted in fabs(10) >= fabs(20) to be true! When I compiled the project with Visual Studio, it gave "warning C4013: 'fabs' undefined; assuming extern returning int". I would normally expect the build to fail in the linking stage. Probably the linker is able to find the fabs but since it was first assumed to be returning int (4 bytes) and fabs returns double (8 bytes), this will result in 4 bytes of the return value being ignored, which can cause funny values. For more about the reason why this behavior is allowed, see my similar trouble with malloc before.

Another interesting fact is that the code was working properly when run from a Simulink s-function. I assume Simulink includes math.h somewhere in its hierarchy. Here is the simplified code:

To prevent Visual Studio from building when 4013 warning exists, go to project Properties - C/C++ - Advanced - Treat Specific Warnings as Errors - Add 4013:



Wednesday, June 15, 2022

String input to Matlab C Mex file

When you call a Matlab C Mex function with a string input, make sure to use single quotes, e.g. 'hello'. If you use double quotes, e.g. "hello", Matlab will crash and burn!

Monday, May 16, 2022

Dangers of C++

Recently I had a strange bug that caused a previously working C++ simulation to fail. It turned out that a logically unrelated portion of code was corrupting the memory and that corruption resulted in changing of parameter values which resulted in instability. Corruption was due to writing out of index. If that index pointed to a memory location outside the boundaries of my program I would get an access violation. Unfortunately, indices were pointing to my programs memory, therefore I did not get any errors from the operating system and had to pin point the bug by trial and error, i.e. commenting out sections of code until I got a stable state and then uncommenting until I got instability. A simplified version of the code:

Friday, May 13, 2022

Simulink: Generating code without model version and date

When you generate code with Simulink, the generated header and source files will have model version and date in code comments. This results in version changes in your version control system even when you have not changed any logic. In order to avoid unnecessary version updates, you should comment out the "Model version" and "C/C++ source code generated on" sections in the ert_code_template.cgt file (Configuration Parameters > Code Generation > Templates > Code Templates).

Dangerous while loop

Today a program I am writing stopped responding. After some debugging effort, I came across a 3rd party function that limited an input angle to the [-180, 180] degrees interval. It was using a while loop to increment or decrement the angle. Unfortunately, I was passing an uninitialized variable to it and its value was -9.2...e+61. Such a large value would take years for the function to limit. Below is the original function constrainAngleWhile(), together with much better alternatives:

Wednesday, April 27, 2022

What does valgrind's "still reachable" message mean?

When I check my programs with valgrind for memory leaks I usually get a "still reachable" result, even if there is no memory leak. An example valgrind output:

HEAP SUMMARY:

    in use at exit: 72,704 bytes in 1 blocks

   total heap usage: 3 allocs, 2 frees, 74,752 bytes allocated

72,704 bytes in 1 blocks are still reachable in loss record 1 of 1

LEAK SUMMARY:

   definitely lost: 0 bytes in 0 blocks

   indirectly lost: 0 bytes in 0 blocks

   possibly lost: 0 bytes in 0 blocks

   still reachable: 72,704 bytes in 1 blocks

On valgrind's doc it says: "still reachable" means your program is probably ok -- it didn't free some memory it could have. This is quite common and often reasonable.

I wrote a simple program:

#include <iostream>

int main() {

    return 0;

}

After I compile and check it with valgrind I get "still reachable". If I comment out the #include line, I don't get "still reachable". I have to research a little bit more.

Wednesday, April 20, 2022

C++ "already defined" error

One of the most frustrating errors that a beginner C++ developer faces is the "already defined" linker error. Below is an example that can cause that error and its three solutions:

For more information, see includeinline and static keywords.