Friday, January 19, 2024

The curse of band-aid solutions

The flexibility inherent in software development can become a curse because it allows developers to implement quick and dirty fixes without fully understanding the root cause of a problem. Suppose you are tasked with writing a factorial function, knowing that factorial(1) = 1 and factorial(2) = 2. You write a function to satisfy these conditions:
double factorial(size_t a) {
    return a;
}
Then, during live tests, you realize that the function should return 6 for an input of 3, and 24 for an input of 4. Instead of investigating the correct mathematical approach, you modify your code by adding if statements, because that is what you know:
double factorial(size_t a) {
    if (a < 3) return a;
    else if (a < 4) return a*(a-1);
    else return a*(a-1)*(a-2);
}
You add new if conditions as failed tests pile up. For such a simple case, all developers agree that this is not the way to go. However, as problems become more complex, they often lack straightforward solutions that a single line prompt to ChatGPT can provide. Also, there is always pressure to get things done quickly and you don't have time to get to the bottom of things. Most engineers yield under pressure which over time leads to a growing mess, dissatisfaction, burnout and resignation.
The optimum strategy is to use a band-aid solution in the short term, make a note of it (preferably in an issue tracking system), and as soon as you get a chance, spend time on how your solution could fail and make it more robust. It is crucial to be interested in the problem rather than merely viewing it as something to be gotten rid of. You never attain perfection, you approach it asymptotically. Those who are curious and have the discipline to conduct thorough root cause analysis will become 100X engineers. Those who don't will be replaced by AI. 

Tuesday, January 16, 2024

Visual Studio C++ debug and release configurations

Visual Studio 2019 C++ debug configuration is more forgiving than release. Examples that a debug build allows but release build does not:
enum E {a = 0, b=1};
E r[3] = {0}; //causes "initializing: cannot convert from int to E"

double a = 0;
E d = (E) a; //causes "typecast: cannot convert from double to E"

typedef struct {
    double d[3] {0}; //causes "an in-class initializer is not allowed for a member 
of an anonymous union in non-class scope"
} S; class C { double s[3] {0}; //causes "cannot specify explicit initializer for arrays" }
Therefore, to make sure that the C/C++ code you generated from Simulink model is suitable for building, in your nightly tests, build in release configuration.

Monday, January 15, 2024

Visual Studio: Include all *.c and *.cpp by default

In Eclipse CDT, implementation files (*c., *.cpp) are included until you exclude them. In Visual Studio 2019, it is the reverse, i.e. files are excluded until you manually include them in your project. To include all files automatically and just exclude the file sim\ert_rtw\ert_main.c file, open your *.vcxproj file with an editor, remove all <CICompile Include = .../> lines and use the following:
<ItemGroup>
    <ClCompile Include="**\*.cpp" />
    <ClCompile Include="**\*.c" Exclude="sim\ert_rtw\ert_main.c" />
</ItemGroup>