Saturday, October 18, 2025

Using clang-cl in Visual Studio

clang-cl

 clang-cl is the command line tool in Visual Studio capable of invoking the clang compiler with the arguments of msvc. In Visual Studio projects one can just flip the toolset and the clang compiler will be chosen. clang has the following positive aspects:

  • better C++ conformance. Examples are that msvc is leniant towards missing 'typename' for dependent types and 'template' for nesting templates; clang picks them up. There are other issues.
  • offers some code improvements like correct member order in constructors and virtuals which override base class
  • detects some performance improvements like advising to use shared_ptr by reference in loops
  • more precise compilation warnings and errors

It has also some drawbacks: 

  • some noisy warnings 
  • does not understand all msvc code. For example the msvc's #import extension is not understood

 Despite using msvc's code analysis the clang compiler was still able to pick up other issues. Some clang warnings are far fetched and one can choose to disable them. This is especially needed for external libraries which one cannot easily patch. To disable warnings one can use the following:

#ifdef __clang__
#pragma clang diagnostic ignored "-Wimplicit-exception-spec-mismatch"
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
#pragma clang diagnostic ignored "-W#pragma-messages"
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
#pragma clang diagnostic ignored "-Wunused-local-typedef"
#endif

 The first one for example is necessary to suppress warnings in MFC. 'delete' should be specified with 'noexcept' but the MFC delete lacks this.


Monday, August 25, 2025

Watch out for hypes in ICT

Hypes

 ICT has a rich history of hypes where people thought that this would be a panacea for all problems. These hypes lasted for some time like paradigms in Thomas Kuhn's theory about evolution of science. From the top of my head we had the following hypes in the past:

  • relational / SQL databases (70's)
  • structural design
  • object oriented design (80's)
  • component based development (90's)
  • design patterns (1995)
  • scrum / agile (2001)
  • AI (2022)

 Many of these hypes were initially promising but not to the extend of solving all problems. They are now part of the current solution domain. We also know now that there are still problems to tackle. 

 Let's see what AI will bring us in the future. For now it's on the level of coding assist but not on the level of designing whole systems. In that part it still cannot replace programmers. There are already studies mitigating the effect of using AI.  It also still makes mistakes. From personal experience it can introduce errors in a code base if you let it run without crosschecking.

 Scrum has brought nothing to ICT except misery. The company I work for took a major loss after embracing it. 

Saturday, August 16, 2025

Careful with AI tooling

AI tooling

 Since some period I started working with AI tooling. Mostly I use Gemini and Visual Studio's Copilot. The experience is a bit of mixed feelings about this. Gemini had some good suggestions but also failed many times. Copilot has good code completion suggestions but misses the mark also occasionally. Copilot's function name suggestions are very welcome.

 Some examples of AI tooling failing are listed here:

  • I asked Gemini for camera sharpness algorithm. It came up with a good algorithm but the actual OpenCV function calls and parameters were incorrect.
  • I asked Gemini to get the real sample time from an 'IMediaSample'. It hallucinated and suggested to use the non existing 'GetSampleTime'. There is a 'GetMediaTime' function but this returns the stream time; i.e. the time since the graph was running and not the time from the start of the video. 
  • I asked Gemini of conversion from UCS-2 to UTF-16. It wrongly suggested to use wstring_convert but wstring_covert is hardbound to std::string as byte_string
  • I asked Gemini for a natural sort algorithm. It came up with a good implementation and a clever trick to circumvent the conversion from string to integer numbers. It lacked though the removal of leading zero's which is essential for the clever trick to work.
  • I had to work on CMake lately but suggestions were often contradictory or using old conventions. In the CMake world things have shifted and perhaps the AI models are trained on old data.

 AI tooling can suggest plain bugs. I was implementing a swap of width and height and Copilot's code complete came up with the following code snippet:

// NOTE: incorrect 
Size sz = ...;
if (sz.GetWidth() < sz.GetHeight())
{
   sz.SetWidth(sz.GetHeight());
   sz.SetHeight(sz.GetWidth());
}

This doesn't swap but sets the width and height on the old height value.

 Conclusion

 AI tooling are helpful; mostly they give better answers than a Google search. It guided me lately through difficult CMake paths some very good answers but also ones who missed the boat. They are still not on the level to be trusted blindly. They also have limited scope for software engineering; e.g. code blocks; algorithms and functions. I am not aware if they can help in refactoring and extending architecture wide solutions.


Debugging GDI drawing

GDI debugging

 The other day I had to debug a hard to track drawing bug. The application is built with the MFC framework so it still uses GDI on places to draw custom controls.

 The incorrect drawing artifact was displayed after an invocation of 'DrawText' with the flag 'DT_CALCRECT'. This was unexpected since with the flag the function doesn't draw and only measures the size. Eventually I realized that GDI batches invocations so perhaps the buggy overdrawing had already taken place before. What was needed to prove this hypothesis:

  •  suppress GDI's caching mechanism through 'GdiSetBatchLimit'.
  •  use direct drawing; so no memory device context

 With this in place indeed it could be seen that the mistake happened earlier in the code and that the 'DrawText' invocation was merely a flush of the GDI batch.

 Be aware that suppressing  GDI's batch might not always work. When the window where the drawing took place was on the primary monitor the batch mode could be turned off but on the second monitor it still cached its calls.

Sunday, July 27, 2025

Watch out for an old VC++ runtime

 VC_redist.x64.exe

 For C/ C++ applications the VC++ runtime needs to be installed on the computer. The other day we experienced crashes when a component developed with a late version of VS2022 was crashing on a fresh installation of Windows 11. It turned out that this Windows 11 still uses an old version of the VC++ runtime which could crash the application (most notably in grabbing a std::mutex lock). After updating the PC with a recent version of 'VC_redist.x64.exe' the problem was solved.

 

Wednesday, July 23, 2025

ark.intel.com

 

Intel's website

 Intel had a wonderful website ark.intel.com where one could lookup the processor and its capabilities. For example information about capable instruction set (e.g. SSE 4.2; AVX; AVX2) was listed there. In a recent visit it was completely overhauled and they have removed (or hide) the possibility to lookup your processor with one click. 

 Great that Intel modernized their website but why destroy a valuable functionality?


Sunday, June 29, 2025

Watch out for atan change in Visual Studio 2022 17.14.6

atan

 Recently we updated Visual Studio 2022 17.14.6 and the regression test reported errors. It turned out that atan implementation was changed resulting a different value for debug vs release builts with CPU's having AVX2. One can recreate this with the following values:

    constexpr double ax        = 38.176459921094995;
    constexpr double ay        = 15.964755390006060;
    const double     dRotation = std::atan(ay/ax);

 We had to relax the equality checks; even for deterministic calculations.


Careful with refactoring

Refactoring issue  Last year we applied a small refactoring in a piece of code. The construct was a parent - child relationship with the chi...