Saturday, November 8, 2025

Issues with Linux port

 

Linux port

 The company I work for decided to port part of our application to Linux. At a first shot we will use WSL and Visual Studio but issues are not over:

  • CMake is the lingua franca of generating cross platform build scripts. CMake is a beast of itself however
  • WSL keeps sometimes its old configuration and source files. It seems that when the source files are read only they are read only on the target WSL system as well. If you edit a file afterwards the update of this file will fail so one won't see their changes. Either make the source files not read only beforehand or clean all files and directories on the WSL host and then start fresh again. Alternatively add the write right to the files on Linux through chmod. 
  • MSVC uses __declspec(dllexport) to export functions from DLL's; gcc doesn't have that.
  • MSVC is pushing security enhanced versions of the CRT through its code analyzer. According to cppreference these functions are standardized albeit as extension (i.e. Annex K of C11). Unfortunately glibc has not implemented them; partially because some dubious reasoning. The API isn't perfect and there are pre-exisiting bounds checking crt but still it's standardized and some people (we) use them. So one ends up writing Windows and Linux specific code even in a layer which supposed to be platform independent.
  • Many of the MSVC C API is Windows specific (e.g. _splitpath; _makepath; _tchdir). Using C alone on Windows platform may therefore still not platform independent.
  • Warning suppression's in pre-compiled header in GCC are ignored in code. This is quite unhandy; especially since some suppression's one want to apply globally to all sources and are therefore are primary candidate to put in pre-compiled header.

It seems that gcc might still contain some basic bugs. The warning about #pragma once in main file (when building a pre-compiled header) is only solved in version 14.

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 Karl Popper's science philosophy. 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)
 All these hypes (except scrum) were useful but not to the extend of solving all problems. They are now part of the current solution domain. We also know now that these 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 (besides that it makes mistakes).

Saturday, August 16, 2025

Careful with AI tooling

AI tooling

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

 On the other hand AI tooling is still full of mistakes. Some examples:

  • 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 suggest to use the non existing 'GetSampleTime'. There is b.t.w. 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 lately of conversion from UCS-2 to UTF-16 and it wrongly suggested to use wstring_convert. However wstring_covert is hardbound to std::string as byte_string

 Even worse that sometimes 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.

 AI tooling can be helpful but are still not on the level to be trusted blindly. They also now help with limited scope; e.g. code blocks; algorithms and functions. I am not aware if they can help in refactoring and extending architecture spanning 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

 

ark.intel.com

 Intel had a wonderful website where one could easily lookup the processor and see what capabilities (e.g. SSE 4.2; AVX; AVX2) it had. In a recent visit it was completely overhauled and they have removed (or hidden) the easy possibility to lookup your processor with one click. Thanks Intel for modernizing their website and destroying 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:

    const double ax          = 38.176459921094995;
    const double ay          = 15.964755390006060;
    const double dblRotation =  atan(ay/ax);

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


Sunday, June 1, 2025

Careful with std::wfstream

wchar_t file streams

 The std::wfstream is similar to std::fstream except it accepts wchar_t. However it does not write std::wchar_t characters to file. Suppose the following code:

   std::wofstream ofs{L"c:\\temp\\1.txt" , std::ios_base::out | std::ios_base::binary};
   ofs.write(L"ABC", 3);

 On the Windows platform this writes just single bytes characters to the file. It uses the codecvt of the imbued locale which translated wchar_t to char. The standard C locale does not handle characters above the 255 so it will fail when using other characters than the extended ASCII character set. It will also fail when writing binary data through the write interface. It can be fixed by using a custom locale which leaves wchar_t unaffected. There was a codeproject article on this but it has been retracted.

 This translation is quite unexpected behavior since the function prototypes are defined in terms of wchar_t. It is also different compared to the wchar_t string streams: std::wstringstream does write wchar_t strings unaffected.

 This article was inspired by a YouTube comment of me where I stated that the C file stream API is less surprising. Of course there is always a clown who thinks better but probably doesn't know anything about above issue. With C stream I/O FILE and 'fwrite' the bytes are transferred to the file without interpretation and alteration.

FILE wrapper

 Jason Turner goes a lengthy way of wrapping the C file stream API but using a wrapper class would probably be simpler:

class c_file
{
public:
   c_file()
      : m_fp(nullptr)
   {
   }
   
   explicit c_file(const std::filesystem::path& rpth, const char* pszMode)
      : m_fp(fopen(rpth.string().c_str(), pszMode))
   {
   }

   ~c_file()
   {
      if (m_fp)
      {
         fclose(m_fp);
      }
   }

   c_file(const c_file&) = delete;

   c_file(c_file&& rOther) noexcept
      : m_fp(std::exchange(rOther.m_fp, nullptr))
   {
   }

   c_file& operator=(const c_file&) = delete;

   c_file& operator=(c_file&& rOther) noexcept
   {
      std::swap(m_fp, rOther.m_fp);
   }

   explicit operator bool() const
   {
      return m_fp;
   }

   size_t read(void* pBuffer, size_t size, size_t count)
   {
      return fread(pBuffer, size, count, m_fp);
   }

   size_t write(const void* pBuffer, size_t size, size_t count)
   {
      return fwrite(pBuffer, size, count, m_fp);
   }

   // etc.

private:
   FILE*    m_fp;
};

Links

Sunday, July 21, 2024

C++ horrible aspects

C++ horrible aspects

 Linus Torvalds described C++ as being a horrible language. While C++ has its dark corners I choose it any day over any other language. Especially compared to C with its major security liabilities. There are some questionable aspects though: 

  • 'rvalue' references becoming 'lvalue' references. Not sure who invented this but he or she should be banned from the committee. Super confusing that a type can change.
  • universal references and perfect forwarding. Again a very confusing idea to reuse the 'rvalue' reference syntax. The reference collapsing rules doesn't make it easier either
  • two phase lookup. Confusing rule which could have been solved by stating that a template definition is only checked at instantiation time. No more need for 'typename' or making types and member functions (non) dependent since at instantiation time all type and context information is known
  • lack of uniformity in STL. For example there is reset and clear. Some algorithm's have _if variants when taking functors; others not.
  • functional programming style over object oriented. Why not make the regex functions member functions? It prevents clutter of std namespace. It will probably also help Intellisense to build up its database which is important help in IDE's these days. 
  • uniform initialization. Again the committee made a mistake. The issue could be fixed by requiring double braces in case constructor invocation (e.g.std::vector<size_t>{{2}})
  • the ranges library has some strange aspects as well as can be seen here

Besides these aspects C++ misses out on an extended standard library. Especially compared to .NET or Java where many things are present in their extensive standard library. One frequently need 3th party libraries (e.g. Boost) for basic things. This could have been alleviated if there was a standard package manger like in Python with de facto libraries but again there isn't.

 Side remark: Linus Torvalds is a technical gifted person but his comments about C++ give the impression that he a hasn't a clue about the language and he just doesn't know what he is talking about. In the meantime many large projects (e.g. GCC; OpenCV) have made the shift and never will go backwards to C.

Monday, June 24, 2024

Careful with that initializer_list part 2

initializer_list

 When using Boost.JSON I stumbled upon the following issue:

boost::json::value jv(1);  // creates a number type
boost::json::value jv{1};  // creates an array type

 The JSON value object has constructor definitions something like these:

struct value
{
   value(int);
   value(double);
   value(std::initializer_list<int>);
};

 This gives the following invocations:

value vl1(1);  // invokes value(int) constructor
value vl2{1};  // invokes value(std::initializer_list<int>); constructor

 This is a know issue in C++. A programming language should be unambiguously be interpretable and the C++ had decided that in such case the initializer_list has precedence. Not sure if that's a good solution since the ambiguity may only appear when running under the debugger or at customer site. The ambiguity can be solved by requiring double braces in case there are overloads like this but the all wise C++ committee has decided otherwise. The uniform initialization problem is still not solved.

 Edit: this behavior has now been patched as of Boost 1.86. If the initializer_list has size 1 it's assumed to be a single value type instead of array. Original behavior can be mimicked by using BOOST_JSON_LEGACY_INIT_LIST_BEHAVIOR. Pretty smart trick t.b.h.

Wednesday, August 30, 2023

Careful with std::ranges

<ranges>

  C++20 has added the the ranges library. Basically it works on ranges instead of iterators but added some subtle constraints to some algorithms. For example consider the lower_bound algorithm:

#include <algorithm>
#include <utility>

using IntPair = std::pair<int, int>;
   
IntPair a[1];

auto it = std::lower_bound(std::cbegin(a), std::cend(a), 1, [](const IntPair& r, int n) { return r.first < n; });

The lower_bound function only expects an asymmetric functor implementing the order between container and search element. To spare on typing out the begin and end iterator one could think to use the ranges library:

auto it = std::ranges::lower_bound(a, 1, [](const IntPair& r, int n) { return r.first < n; });

This gives though a ton of mystic error messages on VStudio:

1>error C2672: 'operator __surrogate_func': no matching overloaded function found
1>error C7602: 'std::ranges::_Lower_bound_fn::operator ()': the associated constraints are not satisfied
1>message : see declaration of 'std::ranges::_Lower_bound_fn::operator ()'

It turns out that the ranges variant expect a functor with all less combinations defined:

struct OpLess
{
   bool operator() (const int n1, int n2) const                 { return n1 < n2; };
   bool operator() (const IntPair& r1, const IntPair& r2) const { return r1.first < r2.first; };
   bool operator() (const IntPair& r, int n) const              { return r.first < n; };
   bool operator() (int n, const IntPair& r) const              { return n < r.first; };
};

auto it = std::ranges::lower_bound(a, 1, OpLess{});

Side note: concepts supposed to give more clearer error messages but are cryptic as well.

External links

Sunday, May 7, 2023

Careful with std::shared_ptr

std::shared_ptr

std::shared_ptr is a C++ smart pointer who takes shared ownership of the pointee. It solves some of the memory problems associated with the C language which are memory leaks; buffer overruns and dangling pointers. The first two can be solved by using std::vector; the first and last one by using std::shared_ptr. shared_ptr has though some sharp edges:

  • one can create cycles between std::shared_ptr (i.e. A points to B; B points to A). The memory isn't released then. Solution is to use std::weak_ptr to break the cycle. Alternatively one can use a raw pointer to point back to the owner.
  • never assign a 'raw' resource to two std::shared_ptr's. Instead once a resource is assigned to a std::shared_ptr use the std::shared_ptr to share that resource.
  • use enabled_shared_from_this to hand out a std::shared_ptr of yourself. This fails in constructor because the std::shared_ptr structure is build after the constructor returns.

Garbage collectors don't suffer from these issues but the runtime price one pays for it is large. Also their non-deterministic destruction may another big hurdle to coop with.

Saturday, January 21, 2023

Scrum is the cancer of ICT

Scrum

  The company I work for decided to switch to a more Agile / Scrum development method in 2017. A hired consultant promised the CEO that with this method we would be more 30% effective. He used some bullshit metrics and use cases found on internet. 

 Since then two major projects have failed to come to a stable product. This was due to the following reasons:

  • sprints of 3 weeks are too short to achieve substantial development.
  • focus on short term - easy achievable goals. A pitfall fueled by easy to check off backlog items and tasks.
  • work on core and foundation has not much attention. This kind of work is hard to show and demonstrate to stakeholders.
  • make small pieces of software and patch / refactor later is not a way to build stable buildings let alone software.
  • lot of administrative overhead with daily standup's; sprint review; grooming sessions; retrospective etc.
  • Agile promised to offer better dealing with shifting requirements but this is a false promise. One cannot design large piece of software and then suddenly decide to do something completely else.

 Not sure why the world has gone mad but our company was doing a lot better beforehand. A false fallacy is often used to compare this method with the waterfall method with rigid requirements once written down. However no company works that way. No company would have continued development knowing that requirements are outdated.

 In the main time our company is now in a difficult spot. This was partly due to changes in the world economy with China protecting its home production and the USA cutting in budgets but the company was also dependent on the projected revenue of the failed products.

Tuesday, August 9, 2022

Watch out for MSVC's std::map's move constructor

move constructor

 The other day I found out that MSVC's std::map move constructor doesn't have noexcept:

map(map&& _Right) : _Mybase(_STD move(_Right)) {}

This means that it can throw when moved and it's not eligible for move_if_noexcept which is used in vector reallocation's. I filed a report but it got rejected. Take care when you want map's to be moveable (which can be a factor compared to copying all nodes).

Friday, July 15, 2022

Watch out for vector one argument constructor

vector constructor

 Aggregate initialization brought us many good things. There is though one nasty pitfall with std::vector. std::vector can be initialized with a size_t to specify its initial size. There is a potential ambiguity since the vector also accepts size_t as its element type:


#include <cassert>
#include <vector>

int main()
{
   std::vector<size_t>  vec0(5);   // vector size is set
   std::vector<size_t>  vec1{5};   // vector size isn't set directly but vector is initialized with 1 element

   assert(vec0.size() == 5);
   assert(vec1.size() == 1);

   std::vector<size_t>  vec2{vec0.size()};  // even worse: vectors do not have the same size now

   return 0;
} 

This is especially a problem with 32 bits code where size_t is an int typedef. A solution is that the C++ committee resolves the ambiguity e.g. by introducing a 2 argument overload for vector constructor (with an extra enum). Until then it's watching out 

Reference:

Wednesday, July 6, 2022

Boost include spam

#include

 Boost libraries are a great addition to C++. However anyone working with Boost lirbaries know that they explode your compile times. For example include adjacency_list for Boost.Graph lead to the following spam:


graph\adjacency_list.hpp
 unordered_set.hpp
  unordered/unordered_set.hpp
   core/explicit_operator_bool.hpp
   functional/hash.hpp
    container_hash/hash.hpp
   move/move.hpp
    move/detail/config_begin.hpp
    move/utility.hpp
     move/detail/config_begin.hpp
     move/detail/config_end.hpp
    move/algorithm.hpp
     move/detail/config_begin.hpp
     move/detail/config_end.hpp
    move/detail/config_end.hpp
   unordered/detail/set.hpp
    unordered/detail/implementation.hpp
     assert.hpp
      C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\assert.h
     core/allocator_traits.hpp
      core/allocator_access.hpp
       core/pointer_traits.hpp
     core/bit.hpp
      cstdint.hpp
     swap.hpp
     type_traits/is_base_of.hpp
     type_traits/is_nothrow_move_assignable.hpp
      type_traits/has_trivial_move_assign.hpp
      type_traits/enable_if.hpp
     type_traits/is_nothrow_move_constructible.hpp
     type_traits/is_nothrow_swappable.hpp
     type_traits/make_void.hpp
     unordered/detail/fwd.hpp
      predef.h
       predef/language.h
        predef/language/stdc.h
         predef/version_number.h
         predef/make.h
          predef/detail/test.h
        predef/language/stdcpp.h
         predef/make.h
        predef/language/objc.h
         predef/make.h
        predef/language/cuda.h
         predef/make.h
       predef/architecture.h
        predef/architecture/alpha.h
         predef/make.h
        predef/architecture/arm.h
         predef/make.h
        predef/architecture/blackfin.h
         predef/make.h
        predef/architecture/convex.h
         predef/make.h
        predef/architecture/e2k.h
         predef/make.h
        predef/architecture/ia64.h
         predef/make.h
        predef/architecture/loongarch.h
         predef/make.h
        predef/architecture/m68k.h
         predef/make.h
        predef/architecture/mips.h
         predef/make.h
        predef/architecture/parisc.h
         predef/make.h
        predef/architecture/ppc.h
         predef/make.h
        predef/architecture/ptx.h
         predef/make.h
        predef/architecture/pyramid.h
         predef/make.h
        predef/architecture/riscv.h
         predef/make.h
        predef/architecture/rs6k.h
         predef/make.h
        predef/architecture/sparc.h
         predef/make.h
        predef/architecture/superh.h
         predef/make.h
        predef/architecture/sys370.h
         predef/make.h
        predef/architecture/sys390.h
         predef/make.h
        predef/architecture/x86.h
         predef/architecture/x86/32.h
          predef/make.h
          predef/architecture/x86.h
           predef/architecture/x86/32.h
           predef/architecture/x86/64.h
            predef/make.h
            predef/architecture/x86.h
             predef/architecture/x86/32.h
             predef/architecture/x86/64.h
         predef/architecture/x86/64.h
        predef/architecture/z.h
         predef/make.h
       predef/compiler.h
        predef/compiler/borland.h
         predef/make.h
        predef/compiler/clang.h
         predef/make.h
        predef/compiler/comeau.h
         predef/make.h
        predef/compiler/compaq.h
         predef/make.h
        predef/compiler/diab.h
         predef/make.h
        predef/compiler/digitalmars.h
         predef/make.h
        predef/compiler/dignus.h
         predef/make.h
        predef/compiler/edg.h
         predef/make.h
        predef/compiler/ekopath.h
         predef/make.h
        predef/compiler/gcc_xml.h
         predef/make.h
        predef/compiler/gcc.h
         predef/compiler/clang.h
         predef/make.h
        predef/compiler/greenhills.h
         predef/make.h
        predef/compiler/hp_acc.h
         predef/make.h
        predef/compiler/iar.h
         predef/make.h
        predef/compiler/ibm.h
         predef/make.h
        predef/compiler/intel.h
         predef/make.h
        predef/compiler/kai.h
         predef/make.h
        predef/compiler/llvm.h
         predef/compiler/clang.h
         predef/make.h
        predef/compiler/metaware.h
         predef/make.h
        predef/compiler/metrowerks.h
         predef/make.h
        predef/compiler/microtec.h
         predef/make.h
        predef/compiler/mpw.h
         predef/make.h
        predef/compiler/nvcc.h
         predef/make.h
        predef/compiler/palm.h
         predef/make.h
        predef/compiler/pgi.h
         predef/make.h
        predef/compiler/sgi_mipspro.h
         predef/make.h
        predef/compiler/sunpro.h
         predef/make.h
        predef/compiler/tendra.h
         predef/make.h
        predef/compiler/visualc.h
         predef/compiler/clang.h
         predef/make.h
         predef/detail/comp_detected.h
        predef/compiler/watcom.h
         predef/make.h
       predef/library.h
        predef/library/c.h
         predef/library/c/_prefix.h
          predef/detail/_cassert.h
           C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include\cassert
            C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\assert.h
         predef/library/c/cloudabi.h
          predef/make.h
         predef/library/c/gnu.h
          predef/make.h
         predef/library/c/uc.h
          predef/make.h
         predef/library/c/vms.h
          predef/make.h
         predef/library/c/zos.h
          predef/make.h
        predef/library/std.h
         predef/library/std/_prefix.h
          predef/detail/_exception.h
         predef/library/std/cxx.h
          predef/make.h
         predef/library/std/dinkumware.h
          predef/make.h
         predef/library/std/libcomo.h
          predef/make.h
         predef/library/std/modena.h
          predef/make.h
         predef/library/std/msl.h
          predef/make.h
         predef/library/std/roguewave.h
          predef/make.h
         predef/library/std/sgi.h
          predef/make.h
         predef/library/std/stdcpp3.h
          predef/make.h
         predef/library/std/stlport.h
          predef/make.h
         predef/library/std/vacpp.h
          predef/make.h
       predef/os.h
        predef/os/aix.h
         predef/make.h
        predef/os/amigaos.h
         predef/make.h
        predef/os/beos.h
         predef/make.h
        predef/os/bsd.h
         predef/os/macos.h
          predef/os/ios.h
           predef/make.h
          predef/make.h
         predef/make.h
         predef/os/bsd/bsdi.h
          predef/os/bsd.h
           predef/os/bsd/bsdi.h
           predef/os/bsd/dragonfly.h
            predef/os/bsd.h
             predef/os/bsd/bsdi.h
             predef/os/bsd/dragonfly.h
             predef/os/bsd/free.h
              predef/os/bsd.h
               predef/os/bsd/bsdi.h
               predef/os/bsd/dragonfly.h
               predef/os/bsd/free.h
               predef/os/bsd/open.h
                predef/os/bsd.h
                 predef/os/bsd/bsdi.h
                 predef/os/bsd/dragonfly.h
                 predef/os/bsd/free.h
                 predef/os/bsd/open.h
                 predef/os/bsd/net.h
                  predef/os/bsd.h
                   predef/os/bsd/bsdi.h
                   predef/os/bsd/dragonfly.h
                   predef/os/bsd/free.h
                   predef/os/bsd/open.h
                   predef/os/bsd/net.h
               predef/os/bsd/net.h
             predef/os/bsd/open.h
             predef/os/bsd/net.h
           predef/os/bsd/free.h
           predef/os/bsd/open.h
           predef/os/bsd/net.h
         predef/os/bsd/dragonfly.h
         predef/os/bsd/free.h
         predef/os/bsd/open.h
         predef/os/bsd/net.h
         predef/os/bsd/bsdi.h
         predef/os/bsd/dragonfly.h
         predef/os/bsd/free.h
         predef/os/bsd/open.h
         predef/os/bsd/net.h
        predef/os/cygwin.h
         predef/make.h
        predef/os/haiku.h
         predef/make.h
        predef/os/hpux.h
         predef/make.h
        predef/os/irix.h
         predef/make.h
        predef/os/ios.h
        predef/os/linux.h
         predef/make.h
        predef/os/macos.h
        predef/os/os400.h
         predef/make.h
        predef/os/qnxnto.h
         predef/make.h
        predef/os/solaris.h
         predef/make.h
        predef/os/unix.h
         predef/make.h
        predef/os/vms.h
         predef/make.h
        predef/os/windows.h
         predef/make.h
         predef/detail/os_detected.h
       predef/other.h
        predef/other/endian.h
         predef/make.h
         predef/library/c/gnu.h
         predef/os/macos.h
         predef/os/bsd.h
          predef/os/bsd/bsdi.h
          predef/os/bsd/dragonfly.h
          predef/os/bsd/free.h
          predef/os/bsd/open.h
          predef/os/bsd/net.h
         predef/platform/android.h
          predef/make.h
         predef/architecture.h
        predef/other/wordsize.h
         predef/architecture.h
         predef/make.h
        predef/other/workaround.h
       predef/platform.h
        predef/platform/android.h
        predef/platform/cloudabi.h
         predef/make.h
        predef/platform/mingw.h
         predef/make.h
        predef/platform/mingw32.h
         predef/make.h
        predef/platform/mingw64.h
         predef/make.h
        predef/platform/windows_uwp.h
         predef/make.h
         predef/os/windows.h
         C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared\ntverp.h
          C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared\ntverp.ver
         predef/detail/platform_detected.h
        predef/platform/windows_desktop.h
         predef/make.h
         predef/os/windows.h
         predef/platform/windows_uwp.h
        predef/platform/windows_phone.h
         predef/make.h
         predef/os/windows.h
         predef/platform/windows_uwp.h
        predef/platform/windows_server.h
         predef/make.h
         predef/os/windows.h
         predef/platform/windows_uwp.h
        predef/platform/windows_store.h
         predef/make.h
         predef/os/windows.h
         predef/platform/windows_uwp.h
        predef/platform/windows_system.h
         predef/make.h
         predef/os/windows.h
         predef/platform/windows_uwp.h
        predef/platform/windows_runtime.h
         predef/make.h
         predef/os/windows.h
         predef/platform/windows_phone.h
         predef/platform/windows_store.h
        predef/platform/ios.h
         predef/os/ios.h
       predef/hardware.h
        predef/hardware/simd.h
         predef/hardware/simd/x86.h
          predef/hardware/simd/x86/versions.h
         predef/hardware/simd/x86_amd.h
          predef/hardware/simd/x86_amd/versions.h
         predef/hardware/simd/arm.h
          predef/hardware/simd/arm/versions.h
         predef/hardware/simd/ppc.h
          predef/hardware/simd/ppc/versions.h
       predef/version.h
     utility/addressof.hpp
    unordered/unordered_set_fwd.hpp
     functional/hash_fwd.hpp
 scoped_ptr.hpp
  smart_ptr/scoped_ptr.hpp
   assert.hpp
    C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\assert.h
   checked_delete.hpp
   smart_ptr/detail/sp_disable_deprecated.hpp
   smart_ptr/detail/operator_bool.hpp
 graph/graph_traits.hpp
  pending/property.hpp
   type_traits.hpp
    type_traits/common_type.hpp
     type_traits/decay.hpp
      type_traits/remove_bounds.hpp
       type_traits/remove_extent.hpp
     type_traits/detail/mp_defer.hpp
    type_traits/conjunction.hpp
    type_traits/copy_cv.hpp
    type_traits/copy_cv_ref.hpp
     type_traits/copy_reference.hpp
    type_traits/disjunction.hpp
    type_traits/extent.hpp
    type_traits/floating_point_promotion.hpp
    type_traits/has_bit_and.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_bit_and_assign.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_bit_or.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_bit_or_assign.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_bit_xor.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_bit_xor_assign.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_complement.hpp
     type_traits/detail/has_prefix_operator.hpp
    type_traits/has_dereference.hpp
     type_traits/detail/has_prefix_operator.hpp
    type_traits/has_divides.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_divides_assign.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_equal_to.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_greater.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_greater_equal.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_left_shift.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_left_shift_assign.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_less.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_less_equal.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_logical_and.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_logical_not.hpp
     type_traits/detail/has_prefix_operator.hpp
    type_traits/has_logical_or.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_minus.hpp
    type_traits/has_minus_assign.hpp
    type_traits/has_modulus.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_modulus_assign.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_multiplies.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_multiplies_assign.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_negate.hpp
     type_traits/detail/has_prefix_operator.hpp
    type_traits/has_new_operator.hpp
    type_traits/has_not_equal_to.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_nothrow_destructor.hpp
     type_traits/has_trivial_destructor.hpp
    type_traits/has_plus.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_plus_assign.hpp
    type_traits/has_post_decrement.hpp
     type_traits/detail/has_postfix_operator.hpp
    type_traits/has_post_increment.hpp
     type_traits/detail/has_postfix_operator.hpp
    type_traits/has_pre_decrement.hpp
     type_traits/detail/has_prefix_operator.hpp
    type_traits/has_pre_increment.hpp
     type_traits/detail/has_prefix_operator.hpp
    type_traits/has_right_shift.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_right_shift_assign.hpp
     type_traits/detail/has_binary_operator.hpp
    type_traits/has_trivial_move_constructor.hpp
    type_traits/has_unary_minus.hpp
     type_traits/detail/has_prefix_operator.hpp
    type_traits/has_unary_plus.hpp
     type_traits/detail/has_prefix_operator.hpp
    type_traits/has_virtual_destructor.hpp
    type_traits/is_abstract.hpp
    type_traits/is_complex.hpp
     C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include\complex
      C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include\ymath.h
    type_traits/is_compound.hpp
    type_traits/is_copy_assignable.hpp
     type_traits/is_noncopyable.hpp
    type_traits/is_float.hpp
    type_traits/is_list_constructible.hpp
    type_traits/is_member_object_pointer.hpp
    type_traits/is_object.hpp
    type_traits/is_scoped_enum.hpp
     type_traits/negation.hpp
    type_traits/is_signed.hpp
    type_traits/is_stateless.hpp
    type_traits/is_trivially_copyable.hpp
    type_traits/is_union.hpp
    type_traits/is_unscoped_enum.hpp
    type_traits/is_unsigned.hpp
    type_traits/is_virtual_base_of.hpp
    type_traits/make_signed.hpp
    type_traits/make_unsigned.hpp
    type_traits/rank.hpp
    type_traits/remove_all_extents.hpp
    type_traits/remove_cv_ref.hpp
    type_traits/type_identity.hpp
    type_traits/integral_promotion.hpp
    type_traits/promote.hpp
   pending/detail/property.hpp
    type_traits/same_traits.hpp
 graph/graph_mutability_traits.hpp
 graph/graph_selectors.hpp
 property_map/property_map.hpp
  assert.hpp
   C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\assert.h
  concept_archetype.hpp
  property_map/vector_property_map.hpp
   property_map/property_map.hpp
   smart_ptr/shared_ptr.hpp
    smart_ptr/detail/shared_count.hpp
     smart_ptr/bad_weak_ptr.hpp
     smart_ptr/detail/sp_counted_base.hpp
      smart_ptr/detail/sp_has_gcc_intrinsics.hpp
      smart_ptr/detail/sp_has_sync_intrinsics.hpp
      smart_ptr/detail/sp_counted_base_std_atomic.hpp
       smart_ptr/detail/sp_typeinfo_.hpp
     smart_ptr/detail/sp_counted_impl.hpp
     cstdint.hpp
    assert.hpp
     C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\assert.h
    smart_ptr/detail/spinlock_pool.hpp
     smart_ptr/detail/spinlock.hpp
      smart_ptr/detail/spinlock_std_atomic.hpp
       smart_ptr/detail/yield_k.hpp
        smart_ptr/detail/sp_thread_pause.hpp
        smart_ptr/detail/sp_thread_sleep.hpp
         smart_ptr/detail/sp_win32_sleep.hpp
    smart_ptr/detail/operator_bool.hpp
    smart_ptr/detail/local_sp_deleter.hpp
     smart_ptr/detail/local_counted_base.hpp
 graph/detail/edge.hpp
  functional/hash.hpp
   container_hash/hash.hpp
 graph/properties.hpp
  assert.hpp
   C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\assert.h
  graph/property_maps/constant_property_map.hpp
  graph/property_maps/null_property_map.hpp
 graph/named_graph.hpp
  functional/hash.hpp
   container_hash/hash.hpp
  optional.hpp
   optional/optional.hpp
    assert.hpp
     C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\assert.h
    optional/bad_optional_access.hpp
    none.hpp
     none_t.hpp
    utility/compare_pointees.hpp
    utility/result_of.hpp
     utility/detail/result_of_variadic.hpp
    optional/optional_fwd.hpp
    optional/detail/optional_config.hpp
    optional/detail/optional_factory_support.hpp
    optional/detail/optional_aligned_storage.hpp
    optional/detail/optional_trivially_copyable_base.hpp
    optional/detail/optional_reference_spec.hpp
    optional/detail/optional_relops.hpp
    optional/detail/optional_swap.hpp
  pending/container_traits.hpp
   next_prior.hpp
    iterator/advance.hpp
   unordered_map.hpp
    unordered/unordered_map.hpp
     functional/hash.hpp
      container_hash/hash.hpp
     unordered/detail/map.hpp
      unordered/unordered_map_fwd.hpp
       functional/hash_fwd.hpp
   C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.29.30133\include\unordered_set
 graph/detail/adjacency_list.hpp
  range/irange.hpp
   assert.hpp
    C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\assert.h
   range/iterator_range.hpp
    range/iterator_range_core.hpp
     assert.hpp
      C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\assert.h
     range/functions.hpp
      range/begin.hpp
       range/config.hpp
       range/iterator.hpp
        range/range_fwd.hpp
        range/mutable_iterator.hpp
         range/detail/extract_optional_type.hpp
         range/detail/msvc_has_iterator_workaround.hpp
        range/const_iterator.hpp
      range/end.hpp
       range/detail/implementation_help.hpp
        range/detail/common.hpp
         range/detail/sfinae.hpp
      range/size.hpp
       range/size_type.hpp
        range/difference_type.hpp
         range/has_range_iterator.hpp
        range/concepts.hpp
         iterator/iterator_concepts.hpp
          concept/detail/concept_def.hpp
          concept/detail/concept_undef.hpp
         range/value_type.hpp
         range/detail/misc_concept.hpp
       range/detail/has_member_size.hpp
        cstdint.hpp
       assert.hpp
        C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt\assert.h
       cstdint.hpp
      range/distance.hpp
       iterator/distance.hpp
      range/empty.hpp
      range/rbegin.hpp
       range/reverse_iterator.hpp
      range/rend.hpp
     range/algorithm/equal.hpp
     range/detail/safe_bool.hpp
    range/iterator_range_io.hpp
  graph/graph_concepts.hpp
   graph/numeric_values.hpp
   graph/buffer_concepts.hpp
    typeof/typeof.hpp
     typeof/message.hpp
     typeof/decltype.hpp
    concept/detail/concept_def.hpp
    concept/detail/concept_undef.hpp
   concept/detail/concept_def.hpp
   concept/detail/concept_undef.hpp
  graph/detail/adj_list_edge_iterator.hpp
  graph/adjacency_iterator.hpp
  assert.hpp

 ...about 600+ files

Thursday, April 21, 2022

Careful with mixing types in loop variables

Loop

 The other day I stumbled upon code which accidentally used a double as end condition:

#include <cstdint>
#include <cstdlib>

constexpr double g_dW = 10;

int main()
{
int res = 0;

for (int n = 0; n < g_dW; ++n)
{
res += std::rand(); // use rand just to have a valid loop
}

return res;
}

One would think that the optimizer Visual Studio 2019 16.13 is smart enough to use integer comparison but this is not the case. VS2019 issues a relative expensive integer to double conversion and comparison:

   
    for (int n = 0; n < g_dW; ++n)
00007FF7C9A01011  movsd       xmm6,mmword ptr [__real@4024000000000000 (07FF7C9A02240h)]  
00007FF7C9A01019  mov         edi,ebx  
00007FF7C9A0101B  nop         dword ptr [rax+rax]  
    {
        res += std::rand();
00007FF7C9A01020  call        qword ptr [__imp_rand (07FF7C9A02188h)]  
00007FF7C9A01026  inc         edi  
00007FF7C9A01028  add         ebx,eax  
00007FF7C9A0102A  movd        xmm0,edi  
00007FF7C9A0102E  cvtdq2pd    xmm0,xmm0  
00007FF7C9A01032  comisd      xmm6,xmm0  
00007FF7C9A01036  ja          main+20h (07FF7C9A01020h)  
    }
    
    return res;
 

The solution is simple to use an integer as block condition:

 constexpr int g_dW = 10;

Therefore watch out that VS2019 does not optimize things automatically.

 

Saturday, March 26, 2022

C++ library requests

Libraries

  Anyone who does serious application development would notice that standard C++ lacks extensive library support on the level of e.g. Java or .NET. For example many applications need the following:

  • GUI
  • graphics
  • diagrams and chart plots
  • object persistence
  • basic cryptography
  • graph algorithms
  • networking
  • database
  • XML; JSON
  • basic linear algebra

 There are 3th party libraries who fulfill this gap but it's always more difficult to get that up and running than if it would be stock present. It would therefore hard to recommend to use C++ for new application development.

Boost

  Boost fulfill some of these gaps. Their quality of libraries vary; some of them are even abandoned and not maintained anymore. Still I would like the following libraries to be incorporated in std as well:

  • call_traits
  • circular buffer
  • container
  • date-time (somewhat in C++20 in chrono)
  • graph
  • ios_state_saver
  • iterator_range (somewhat in C++20 in ranges)
  • serialization (but without the implicit by ref / by value assumptions)
  • signal / slot
  • string_algo
  • tribool
  • ublas 
  • unit

Sunday, February 20, 2022

Windows spotlight not working

Windows spotlight

 Windows spotlight is responsible for those nice aesthetic pictures on the logon screen. Somehow it was broken on my machine and I was deprived of this feature. Even when one selected the option (under 'settings', 'personalization' 'lock screen'), it would jump to normal picture mode. 

 Google didn't help at first (their search results become worse and worse over the years) until I got the tip from 'Software Test Tips': some necessary background apps where disabled. After enabling the app 'settings' (under 'settings'; 'privacy'; 'background apps') rebooting and waiting some time it works now.

Issues with Linux port

  Linux port  The company I work for decided to port part of our application to Linux. At a first shot we will use WSL and Visual Studio bu...