Skip to content
  • Junio C Hamano's avatar
    hashmap_for_each_entry(): workaround MSVC's runtime check failure #3 · 0ad621f6
    Junio C Hamano authored
    
    
    The OFFSETOF_VAR(var, member) macro is implemented in terms of
    offsetof(typeof(*var), member) with compilers that know typeof(),
    but its fallback implemenation compares &(var->member) and (var) and
    count the distance in bytes, i.e.
    
        ((uintptr_t)&(var)->member - (uintptr_t)(var))
    
    MSVC's runtime check, when fed an uninitialized 'var', flags this as
    a use of an uninitialized variable (and that is legit---uninitialized
    contents of 'var' is subtracted) in a debug build.
    
    After auditing all 6 uses of OFFSETOF_VAR(), 1 of them does feed a
    potentially uninitialized 'var' to the macro in the beginning of the
    for() loop:
    
        #define hashmap_for_each_entry(map, iter, var, member) \
                for (var = hashmap_iter_first_entry_offset(map, iter, \
                                                        OFFSETOF_VAR(var, member)); \
                        var; \
                        var = hashmap_iter_next_entry_offset(iter, \
                                                        OFFSETOF_VAR(var, member)))
    
    We can work around this by making sure that var has _some_ value
    when OFFSETOF_VAR() is called.  Strictly speaking, it invites
    undefined behaviour to use NULL here if we end up with pointer
    comparison, but MSVC runtime seems to be happy with it, and most
    other systems have typeof() and don't even need pointer comparison
    fallback code.
    
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    Signed-off-by: default avatarJohannes Schindelin <johannes.schindelin@gmx.de>
    Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    0ad621f6