struct alignment still not working for me

I’ve brought this up before, apparently solved then, but it keeps causing problems for me:

When adding 64 bit support for my Zip classes, I need to declare a structure for accessing a C struct on all platforms (OSX, Windows, Linux).

The C struct appears to use no special alignment pragmas, meaning it uses whatever the ABIs on the various platforms use as default.

However, it already turned out that using an aligment attribute of 0 does not, as opposed to the docs, align the struct correctly for both 32 and 64 bit on OSX, as far as I could make it out.

To solve this, I had to declare two structs, and use the Compatibility settings to have one used for 32 bit and one for 64 bit builds

But now this doesn’t seem to work right either because “MS Visual Studio C++ defines UInt and ULong both as UInt32, whereas XCode defines uLong as UInt64”. Meaning that a C struct using UInt needs to use a UInt32 on Windows and UInt64 on OSX. But since the Compat flags make no difference between TargetWindows and TargetMacOS, I can neither make a single struct for both platforms nor two structs that can co-exist in the same project.

This is such a pain.

Any suggestions on how to deal with this, apart from changing the code from using structs to using MemoryBlocks?

[quote=240540:@Thomas Tempelmann]The C struct appears to use no special alignment pragmas, meaning it uses whatever the ABIs on the various platforms use as default.

However, it already turned out that using an aligment attribute of 0 does not, as opposed to the docs, align the struct correctly for both 32 and 64 bit on OSX, as far as I could make it out.[/quote]

Not that it solves your issue with ‘long’ differing across platforms, but could you post the structure declaration and your expectation about how it should be laid out?

From /usr/include/zlib.h:

[code]typedef struct z_stream_s {
Bytef next_in; / next input byte /
uInt avail_in; /
number of bytes available at next_in /
uLong total_in; /
total nb of input bytes read so far */

Bytef    *next_out; /* next output byte should be put there */
uInt     avail_out; /* remaining free space at next_out */
uLong    total_out; /* total nb of bytes output so far */

char     *msg;      /* last error message, NULL if no error */
struct internal_state FAR *state; /* not visible by applications */

alloc_func zalloc;  /* used to allocate the internal state */
free_func  zfree;   /* used to free the internal state */
voidpf     opaque;  /* private data object passed to zalloc and zfree */

int     data_type;  /* best guess about the data type: binary or text */
uLong   adler;      /* adler32 value of the uncompressed data */
uLong   reserved;   /* reserved for future use */

} z_stream;[/code]

I just realize that Windows defines ULONG but not uLong. I have the information about the times from someone else who dug into this issue because I cannot build for Windows (no license) so I can’t debug this myself, unfortunately (still waiting for an IDE that can run 64 builds in the debugger so I don’t need a license just for this)

The file zconf.h has these decls:

typedef unsigned int uInt; /* 16 bits or more */ typedef unsigned long uLong; /* 32 bits or more */

Which suggests that there should indeed be no problem here, and my claim (that is second-hand information) about the uLong type being 32 bit on Windows isn’t valid.

But the tester has made changes according to his beliefs, and also changed the alignment to 0 (from 16, which is what I did set it to), and it works for him with that.

I guess the fact that the IDE’s struct editor still shows the wrong sizes for 64 bit does add to the confusion of said user, too.

Joe, it appears that “int” and “long” are indeed 32 bit long on Windows, see here:

http://stackoverflow.com/questions/384502/what-is-the-bit-size-of-long-on-64-bit-windows

Do you concur?

Which tells me that we’re still lacking a “smart” int type that’s 64bit on OSX and Linux and 32bit on Windows. Something like “NativeInt” and “NativeUInt”, for instance. Which, even if we’re asking for it now, will probably take another 2 years at least, as experience tells…

So, with this problem of needing different structs for Win and OSX/Linux, I thought I’d use a trick that I used in the past, when it worked just fine:

I’d save the project in XML format (or, rather use my tool Arbed) to change the “Compatibility” value to include this extra platform Target check. Like this:

Old:

<Compatibility>(TargetDesktop and (Target64Bit))</Compatibility>

New:

<Compatibility>(TargetDesktop and Target64Bit and (TargetMacOS or TargetLinux))</Compatibility>

And then add another copy of the same struct with this compat value:

<Compatibility>(TargetDesktop and Target64Bit and not (TargetMacOS or TargetLinux))</Compatibility>

Believe it or not - with the old Real Studio IDE this worked, because - it appears - that it aked the Compiler to resolve this constant expression (or maybe rather wrapped the struct into an #if … clause using this expression).

But the new Xojo IDE isn’t that smart. It appears to check these values itself, and thereby breaks this could-have-been-great solution.

It would have been too much to expect that a newer IDE would do the smart thing and let the compiler do the work, I guess?

So, with that, structs are again totally unusable for universal builds thanks to someone’s short-sightedness. And don’t tell me that this is a hack - I had documented this ability many years ago already, along with a feature request to support this officially. But instead of doing that, nope - better break it altogether, and giving us developers even more pain now instead of giving it one more thought, which could have provided a great solution for this struct issue now.

More like good luck that it worked
It wasnt intentional but happened to work
No longer

[quote=240591:@Thomas Tempelmann]
And don’t tell me that this is a hack - I had documented this ability many years ago already, along with a feature request to support this officially. But instead of doing that, nope - better break it altogether, and giving us developers even more pain now instead of giving it one more thought, which could have provided a great solution for this struct issue now.[/quote]
And no breaking it isn’t a bug as it required you hacking the project file to make it work
You documenting it doesn’t mean WE committed to support what you happened to find by hacking the project file
Otherwise we’d have exposed something to let you do this right in the IDE - which was never done

I’ve now spent another 2 hours just to figure out the correct alignment for Win 64 bit and have stopped using Structures altogether in my Zip code, reverting to good old MemoryBlocks.