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 5 years ago to switch to a more Agile / Scrum development method. A consultant promised the CEO that with this method we would be more effective and he used some bullshit use case found on internet. 

Since then two major projects have failed 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. Hard to show and demonstrate to your stakeholders this kind of work.
  • make small pieces and 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.

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.


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.

 

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 constraint...