On 27. 5. 2026 10:28, Timofei Zhakov wrote:
On Tue, May 26, 2026 at 6:27 PM Branko Čibej <[email protected]> wrote:

    On 26. 5. 26 18:09, [email protected] wrote:
    Author: ivan
    Date: Tue May 26 16:09:14 2026
    New Revision: 1934646

    Log:
    Resolve compiler warning (C4312: 'type cast': conversion from 'unsigned int'
    to 'void *' of greater size).

    * subversion/libsvn_repos/rev_hunt.c
       (find_interesting_revisions): Use "1" instead of 0xdeadbeef as non-null
        pointer for hashtable.

    Modified:
        subversion/trunk/subversion/libsvn_repos/rev_hunt.c

    Modified: subversion/trunk/subversion/libsvn_repos/rev_hunt.c
    
==============================================================================
    --- subversion/trunk/subversion/libsvn_repos/rev_hunt.c     Tue May 26 
15:32:31 2026        (r1934645)
    +++ subversion/trunk/subversion/libsvn_repos/rev_hunt.c     Tue May 26 
16:09:14 2026        (r1934646)
    @@ -1198,7 +1198,7 @@ find_interesting_revisions(apr_array_hea
            svn_hash_sets(duplicate_path_revs,
                          apr_psprintf(result_pool, "%s:%ld", path_rev->path,
                                       path_rev->revnum),
    -                    (void *)0xdeadbeef);
    +                    "1");
if (path_rev->revnum <= start)
              break;

    That dead beef was there because we're using the hash table as a
    set, not a dictionary; only the keys matter. It was intentionally
    an invalid pointer so that the code would crash in a very
    recognisable way (better than NULL) if someone ever tried to
    dereference the value from the hash table. If you're fixing some
    useless compiler warning – frankly, a promotion that doesn't lose
    data shouldn't warn at all, this is C, after all – then at least
    replace it with NULL instead of a valid pointer that could one day
    hide a real bug.

    Yes, I understand that not everyone likes my approach to defence
    against incorrect code. :)


Do I misunderstand something or since when on Earth do we have restrictions to assign a 32bit value to a 64bit variable (not the other way) which doesn't truncate any data?

From the documentation about this warning https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4312:

[[[
This warning detects an attempt to assign a 32-bit value to a 64-bit pointer type, for example, casting a 32-bit int or long to a 64-bit pointer.

This can be an unsafe conversion even for pointer values that fit in 32 bits when sign extension occurs. If a negative 32-bit integer is assigned to a 64-bit pointer type, sign extension causes the pointer value to reference a memory address different from the value of the integer.
]]]

If as the article says it's about the signed values, would casting it to an unsigned int and then to void* fix it? I mean to do something like:

[[[
(void *)(unsigned int)0xdeadbeef
]]]

Also the same article suggests an example that it's okay to do the same thing with an int64. I assume the same is true about a size_t. It could also be a way to shut the compiler up.

Maybe (void *)(uintptr_t)0xdeadbeef

MSVC has inttypes.h these days and there's a standard pointer-sized unsigned integer type. So why not use it.

Okay, technically casting a magic number to a pointer is in fact an undefined behaviour

Ha. No, it's not. Using that pointer may invoke interesting /implementation-defined/ behaviour. Just setting its value without dereferencing it is ... OK, though slightly on the exciting side: [1]

Any integer can be cast to any pointer type. Except for the null pointer constants such as NULL (which doesn't need a cast), the result is implementation-defined, may not be correctly aligned, may not point to an object of the referenced type, and may be a trap representation.


 but here it is the idea so if anyone ever tries to dereference it, it leads to a crash. I guess NULL also doesn't work because apr_hash_get() already returns NULL if the key is not present.

Which is probably why I used something other than NULL in the first place, yes.

-- Brane

[1] https://en.cppreference.com/c/language/cast

Reply via email to