On Wed, Apr 05, 2023 at 02:50:36PM +0300, Eli Zaretskii wrote:
> > We don't need to make changes to stop these warnings if it is going
> > to be difficult to do so.
> 
> But is it, in fact, difficult?  Are there any problems with using
> intptr_t, or (if we fear of it being unsupported on some platform)
> with defining a macro that will yield 'long' on all platforms except
> Windows, where it will yield 'intptr_t'?  (Since MinGW uses GCC as the
> compiler, we can rely on 'intptr_t' to be available there.)

It depends on how much of the code would be affected, as I said in my
previous message.

Might it be better to round-trip through intptr_t rather than through
a pointer type?  This means making this change:

diff --git a/tp/Texinfo/XS/parsetexi/tree_types.h 
b/tp/Texinfo/XS/parsetexi/tree_types.h
index 9d5e81d005..aedbeaccaa 100644
--- a/tp/Texinfo/XS/parsetexi/tree_types.h
+++ b/tp/Texinfo/XS/parsetexi/tree_types.h
@@ -17,6 +17,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <stdlib.h>
+#include <stdint.h>
 
 #include "command_ids.h"
 #include "element_types.h"
@@ -57,7 +58,7 @@ enum source_mark_status {
 typedef struct KEY_PAIR {
     char *key;
     enum extra_type type;
-    struct ELEMENT *value;
+    intptr_t value;
 } KEY_PAIR;
 
 typedef struct ELEMENT_LIST {

and consequent changes throughout the code.  (I've got this in progress
but want to check if it's worth doing before I finish it.)

This would mean that the chains of conversions

(integer type) -> (pointer type) -> (integer type)
(pointer type) -> (pointer type) -> (pointer type)

become

(integer type) -> intptr_t -> (integer type)
(pointer type) -> intptr_t -> (pointer type)

The following text is from some version of the C standard, so doing
a round trip through intptr_t seems to be the recommended use, rather
than changing types or using casts at either end:

  The following type designates a signed integer type with the property
  that any valid pointer to void can be converted to this type, then
  converted back to pointer to void, and the result will compare equal
  to the original pointer:
  
    intptr_t

(From here, page 291:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf)

(We could end up with new warnings about casts between integer types
of different widths, but the idea of this seems less harmful than
casts involving pointers.)

> I think you are forgetting the endianness.  With at least one of the
> two possible endianness possibilities, isn't it true that casting to a
> narrower type can result in catastrophic loss of significant bits, if
> you cast between integers and pointers, or vice versa?

I've never heard of that before.  So you are saying if you have a small
integer (like 5) stored in a narrow integer type, cast this to a wider
pointer type, and then cast it back to the same integer type, then
something catastrophic happens?  How does that work?

> If we don't want to change the type, we can assign the value to a
> variable of the suitable width:
> 
>   void *elptr = value;
>   add_associated_info_key (e->extra_info, key, elptr, extra_integer);

How is that different to the following?

    add_associated_info_key (e->extra_info, key, (void*) value, extra_integer);

Reply via email to