www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Different struct sizeof between linux and windows

reply Andre Pany <andre s-e-a-p.de> writes:
Hi,

I try to write a wrapper for a library. I translated the C++ 
header coding.
While the wrapper is working fine in linux, on windows the 
library complains
the struct size is too small while calling it.
This is the reduced example:

import core.stdc.time: time_t;
import std.stdio;
	
enum Bar
{
	UNDEFINED = 0,
}
	
struct Foo1
{
    Bar bar;
}
	
struct Foo2
{
    time_t issuedAt;
    Bar bar;
}
	
struct Foo3
{
    time_t issuedAt;
}

void main()	
{
	writeln(Foo1.sizeof);
	writeln(Foo2.sizeof);
	writeln(Foo3.sizeof);
}


I compile the application using dub --arch=x86_64 on windows and
just dub on linux.

Results on linux:
4
16
8

Results on windows:
4
8
4

Is this behavior correct?

Kind regards
André
Jun 16 2016
parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Friday, 17 June 2016 at 06:54:36 UTC, Andre Pany wrote:
 Is this behavior correct?
Yes. time_t is defined as C long on Linux (meaning it'll be 64-bit in 64-bit programs), however it's always 32-bit on the Windows C runtimes we use.
Jun 17 2016
next sibling parent Andre Pany <andre s-e-a-p.de> writes:
On Friday, 17 June 2016 at 07:11:28 UTC, Vladimir Panteleev wrote:
 On Friday, 17 June 2016 at 06:54:36 UTC, Andre Pany wrote:
 Is this behavior correct?
Yes. time_t is defined as C long on Linux (meaning it'll be 64-bit in 64-bit programs), however it's always 32-bit on the Windows C runtimes we use.
Thanks for clarification. Kind regards André
Jun 17 2016
prev sibling parent reply Kagamin <spam here.lot> writes:
time_t is 64-bit on windows: 
https://msdn.microsoft.com/en-us/library/1f4c8f33.aspx
Jun 17 2016
parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Friday, 17 June 2016 at 13:11:35 UTC, Kagamin wrote:
 time_t is 64-bit on windows: 
 https://msdn.microsoft.com/en-us/library/1f4c8f33.aspx
Windows does not have the concept of "time_t". The C runtime in use does. We use the DigitalMars C runtime for the 32-bit model, which is the default one. The Microsoft one is used for 64-bit and 32-bit COFF. I'm not sure how the MS C library deals with time_t, however the time() function (as exported from the library file / DLL) is the 32-bit version. If I were to guess, the C headers define a macro which redirects time() calls to the 64-bit version when appropriate. The D bindings don't copy that behavior.
Jun 17 2016
next sibling parent reply Kagamin <spam here.lot> writes:
On Friday, 17 June 2016 at 13:21:04 UTC, Vladimir Panteleev wrote:
 Windows does not have the concept of "time_t". The C runtime in 
 use does.

 The D bindings don't copy that behavior.
D defining C runtime type different from C runtime causes this error.
Jun 17 2016
parent reply Vladimir Panteleev <thecybershadow.lists gmail.com> writes:
On Friday, 17 June 2016 at 16:16:48 UTC, Kagamin wrote:
 On Friday, 17 June 2016 at 13:21:04 UTC, Vladimir Panteleev 
 wrote:
 Windows does not have the concept of "time_t". The C runtime 
 in use does.

 The D bindings don't copy that behavior.
D defining C runtime type different from C runtime causes this error.
If I were to import the time() function from MSVCR*.dll, what size its return value would be?
Jun 17 2016
parent Kagamin <spam here.lot> writes:
On Friday, 17 June 2016 at 16:25:15 UTC, Vladimir Panteleev wrote:
 If I were to import the time() function from MSVCR*.dll, what 
 size its return value would be?
MSVC runtime dll doesn't export `time` function, it exports _time32 and _time64. `time` is a wrapper in the import library, its time_t is probably 32-bit for binary compatibility with code compiled before VC2005 that first migrated to 64-bit time_t by default.
Jun 20 2016
prev sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, June 17, 2016 13:21:04 Vladimir Panteleev via Digitalmars-d-learn 
wrote:
 On Friday, 17 June 2016 at 13:11:35 UTC, Kagamin wrote:
 time_t is 64-bit on windows:
 https://msdn.microsoft.com/en-us/library/1f4c8f33.aspx
Windows does not have the concept of "time_t". The C runtime in use does. We use the DigitalMars C runtime for the 32-bit model, which is the default one. The Microsoft one is used for 64-bit and 32-bit COFF. I'm not sure how the MS C library deals with time_t, however the time() function (as exported from the library file / DLL) is the 32-bit version. If I were to guess, the C headers define a macro which redirects time() calls to the 64-bit version when appropriate. The D bindings don't copy that behavior.
The VS C runtime uses a macro to indicate whether time_t should be treated as 32-bit or 64-bit on 32-bit systems. I thought that the default was 32-bit, but it looks like it's actually 64-bit, with the macro being _USE_32BIT_TIME_T. https://msdn.microsoft.com/en-us/library/1f4c8f33(v=vs.140).aspx I guess that that the correct way to handle that would be to make it so that druntime defines it as 64-bit by default and then has a version identifier to change the behavior, but I don't know how that sort of thing has been handled with the Win32 stuff in general. In the case of the stupid unicode-related macros, IIRC, the solution is to just force you to use either the A or W functions explicitly (preferably the W functions) rather than making either of them the default or using a version identifier. That approach really isn't an option here though, since the names don't changee but rather the types. - Jonathan M Davis
Jun 17 2016