Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi.
I mainly code with vs code on Windows for C/C++. When the code that runs completely in this environment moved to Linux, I noticed that the datatypes were of different sizes.
These are structs, bitwise operators, and primitive data types.
I'm using windows 10(64), ubuntu zorin(64). centos8(64).

First, here is the result.

               Windows(64) | ZORIN(64)  | Centos 8
CTE                12           9           9
GTE                20          32          32
unsigned int        4           4           4
uint16_t            2           2           2
uint_fast16_t       4           8           8
long                4           8           8
ulong               8           8           8
ulong32             4           8


It makes too big a difference as in the results. The Windows editor program that creates this file is 32-bit.
And all of these tests were done by npm run build during NAPI development of node.js.
I would like to know how to maintain the compatibility of data types in the OS(windows, linux) and compiler environment, and even in 32bit and 64bit environments.

The data types and structures are as follows.

What I have tried:

typedef struct _CTE_
{ 
    unsigned char Signature[3];
 	unsigned char Version[3];
	unsigned char core[1];
	unsigned char editmode : 1;	
	unsigned int : 8;   //padding
} CTE;

typedef struct _GTE_
{
	unsigned char LTL : 1;	  
	unsigned char transtalte : 1; 
	unsigned char country : 8;	 
	unsigned int age : 6;	
	uint_fast16_t count;
	uint_fast16_t trans;
	uint_fast16_t trans_b;
} GTE;

    cout << "CTE: " << sizeof(struct _CTE_) << endl;
    cout << "GTE: " << sizeof(struct _GTE_) << endl;
    cout << "unsigned int: " << sizeof(unsigned int) << endl;
    cout << "uint16_t" << sizeof(uint16_t) << endl;
	cout << "uint_fast16_t: " << sizeof(uint16_t) << endl;
	cout << "size of long: " << sizeof(long) << endl;
	cout << "size of ulong: " << sizeof(ULONG) << endl;
	cout << "size of ulong32: " << sizeof(ULONG32) << endl;
	cout << "size of ulong64: " << sizeof(ULONG64) << endl;
Posted
Updated 5-Apr-21 4:36am
v6
Comments
Richard MacCutchan 5-Apr-21 7:25am    
At a guess you are compiling for 32 bits in Windows, and 64 in Linux. Check your compiler options and settings.

Richard's guess is a good one. Further to that, the size of uint_fast16_t can vary from platform to platform, depending on what size is fastest to fetch on each.
 
Share this answer
 
Comments
Chopin2001 5-Apr-21 18:02pm    
Thanks.
Further to what Richard and Greg have said, there are a couple of other things that you can look into. GCC has a -mms-bitfields compiler flag that aligns bitfields in the same order as Microsoft VSCC, and #pragma ms_struct on to provides the same struct/union layout as MS. The latter generates an unknown pragma warning when compiling in 64 bit mode, but there's also __attribute__((ms_struct)), which does the same thing, and does not generate a warning. You'll probably have to do some testing to get the right combination of flags/pragmas/attributes to see if you can get your structs to lay out in the same order on all systems.
Structure-Layout Pragmas (Using the GNU Compiler Collection (GCC))[^]
x86 Options (Using the GNU Compiler Collection (GCC))[^]

Also note what Fixed width integer types (since C99) - cppreference.com[^] says about _fastn_t integer types : i.e.
Quote:
fastest [un]signed integer type with width of at least 8, 16, 32 and 64 bits respectively
This indicates that fast types only guarantee a minimum width, not an exact width, so using them where portability of data is required is not recommended.
 
Share this answer
 
Comments
Chopin2001 5-Apr-21 18:00pm    
Your answer helps me to figure it out what I needs...
I looked for more resources related to your answer.
I will check my datatype again based on this.
#pragma pack(push, 1)
struct pack
{
char flags; //size 1
int seq; //size 4
}
#pragma pack(pop)
result : 5

#pragma pack(push, 2)
struct pack
{
char flags; //size 1
int seq; //size 4
}
#pragma pack(pop)
result 6

Thanks
After I posted this question, I looked again at the C PRIMER PLUS book. In this book, C is said to have the same size as an unsigned int(32), even if it is a single 1-bit structure.
 
Share this answer
 
Comments
Richard MacCutchan 5-Apr-21 9:03am    
I have compiled for 32 and 64 bits on Windows, and it always generates a 32 bit wide variable. On Linux it generates 64 bit wide, although I was unable to build for 32 bit, owing to some missing files. Try using the -m32 option on your build and see what results you get.
Chopin2001 5-Apr-21 18:05pm    
I haven't been able to find a way to apply the -m32 option in npm run build.
But your answer is worth remembering to me.
Thanks a lot.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900