Thread (1 message) 1 message, 1 author, 2020-09-25

Re: [PATCH 10/10] hashmap_for_each_entry(): work around MSVC's run-time check failure #3

From: Junio C Hamano <hidden>
Date: 2020-09-25 18:38:45
Subsystem: the rest · Maintainer: Linus Torvalds

Possibly related (same subject, not in this thread)

"Johannes Schindelin via GitGitGadget" [off-list ref]
writes:
From: Johannes Schindelin <redacted>

When compiling Git in Visual C, we do not have the luxury of
support for `typeof()`, and therefore `OFFSETOF_VAR()` unfortunately
has to fall back to pointer arithmetic.
Sigh.

Short of changing the signature of hashmap_put_entry() and friends
to also take the type of these variables, I do not see any kosher
way to reimplement the users of OFFSETOF_VAR() to help compilers
without typeof() offhand.  As a one-time annotation, the unfortunate
noise we see in this patch may be tolerable, but what may make this
approach unsustainable is that average programmers would not know,
without compiling with that particular compiler, if their new
variable that points at a hash_entry needs to have an oterwise
unnecessary initialization.  Also the variables that are left
uninitialized by this patch may later require such an initialization.

Of course, it does not help that this workaround relies on an
undefined behaviour, as you pointed out.
When compiling code using the `hashmap_for_each_entry()` macro in Debug
mode, this leads to the "run-time check failure #3" because the variable
passed as `var` are not initialized, yet we calculate the pointer
difference `&(var->member)-var`.
Whoa, wait.  If it is just that macro, can we perhaps do something
like the attached patch?
This "run-time check failure" causes a scary dialog to pop up.

Work around this by initializing the respective variables.

Note: according to the C standard, performing pointer arithmetic
with `NULL` is not exactly well-defined, but it seems to work
here, and it is at least better than performing pointer arithmetic
with an uninitialized pointer.
 hashmap.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hashmap.h b/hashmap.h
index ef220de4c6..49cd8a8e92 100644
--- a/hashmap.h
+++ b/hashmap.h
@@ -449,7 +449,7 @@ static inline struct hashmap_entry *hashmap_iter_first(struct hashmap *map,
  * containing a @member which is a "struct hashmap_entry"
  */
 #define hashmap_for_each_entry(map, iter, var, member) \
-	for (var = hashmap_iter_first_entry_offset(map, iter, \
+	for (var = NULL, var = hashmap_iter_first_entry_offset(map, iter, \
 						OFFSETOF_VAR(var, member)); \
 		var; \
 		var = hashmap_iter_next_entry_offset(iter, \
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help