Discussion:
C vs C++ structure alignment
(too old to reply)
J
2014-02-28 02:14:08 UTC
Permalink
Raw Message
I have a structure in default-aligned space (no command line parameter etc)

and I don't know how much detail is required so this is a slightly more
complex example... it has a 64 bit value in a structure that followed 3
dword values... so it padded a dword before so the 64bit member was
aligned on a 64 bit boundary.

wpp386 did this
wcc386 did not do this

fairly sure watcom before 2.0 did not do this....

my fix is to reverse that and the next member so there's 4 dword values
before the the qword value

----------------------------

// I don't know if watcom falls under this...
#if defined( HAS_STDINT )
/* An unsigned integer type that is 64 bits long. */
typedef uint64_t _64;
#endif

typedef _64 THREAD_ID;


struct threads_tag
{
// these first two items MUST
// be declared publically, and MUST be visible
// to the thread created.
void* param;
void* (*proc)( struct threads_tag * );
void* (*simple_proc)( void* );
THREAD_ID thread_ident;
char * thread_event_name; // might be not a real thread.
};

----------------------------
Jiri Malak
2014-02-28 06:12:47 UTC
Permalink
Raw Message
Sorry, but again absolutely useless information.
Again, OW has "some" problem or "something" is wrong in OW.
blabla

You don't give here serious report with compilable code sample, with
switches used for compillation, used platform etc.

Bellow is sample code which I used for quick test.

#include <stdint.h>
typedef uint64_t _64;

typedef _64 THREAD_ID;

struct threads_tag
{
// these first two items MUST
// be declared publically, and MUST be visible
// to the thread created.
void* param;
void* (*proc)( struct threads_tag * );
void* (*simple_proc)( void* );
THREAD_ID thread_ident;
char * thread_event_name; // might be not a real thread.
char x;
};

struct threads_tag t1 = {
(void *)1,
(void *(*)(struct threads_tag *))2,
(void *(*)(void *))3,
4,
(char *)5,
6
};

compilator outputs

C:\dev\test>wpp386 T5.c -fo=wpp386.obj
Open Watcom C++ x86 32-bit Optimizing Compiler
Version 2.0 beta Feb 19 2014 14:09:13 (32-bit)
Copyright (c) 2002-2014 The Open Watcom Contributors. All Rights Reserved.
Portions Copyright (c) 1989-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
T5.c: 26 lines, included 564, no warnings, no errors
Code size: 0

C:\dev\test>wcc386 T5.c -fo=wcc386.obj
Open Watcom C x86 32-bit Optimizing Compiler
Version 2.0 beta Feb 19 2014 14:03:34 (32-bit)
Copyright (c) 2002-2014 The Open Watcom Contributors. All Rights Reserved.
Portions Copyright (c) 1984-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
See http://www.openwatcom.org/ for details.
T5.c: 26 lines, included 311, 0 warnings, 0 errors
Code size: 0

C:\dev\test>

disassembled wcc386.obj

Module: C:\dev\test\T5.c
GROUP: 'DGROUP' CONST,CONST2,_DATA

Segment: _TEXT BYTE USE32 00000000 bytes

Routine Size: 0 bytes, Routine Base: _TEXT + 0000

No disassembly errors

Segment: CONST DWORD USE32 00000000 bytes

Segment: CONST2 DWORD USE32 00000000 bytes

Segment: _DATA DWORD USE32 00000020 bytes
0000 _t1:
0000 01 00 00 00 02 00 00 00 03 00 00 00 00 00 00 00 ................
0010 04 00 00 00 00 00 00 00 05 00 00 00 06 00 00 00 ................

disassembled wpp386.obj

Module: C:\dev\test\T5.c
GROUP: 'DGROUP' CONST,CONST2,_DATA,_BSS

Segment: _TEXT BYTE USE32 00000000 bytes

Routine Size: 0 bytes, Routine Base: _TEXT + 0000

No disassembly errors

Segment: CONST BYTE USE32 00000000 bytes

Segment: CONST2 BYTE USE32 00000000 bytes

Segment: _DATA PARA USE32 00000020 bytes
0000 threads_tag near t1:
0000 01 00 00 00 02 00 00 00 03 00 00 00 00 00 00 00 ................
0010 04 00 00 00 00 00 00 00 05 00 00 00 06 00 00 00 ................

Segment: _BSS BYTE USE32 00000000 bytes

BSS Size: 0 bytes


As you see nothing is wrong. Maybe you have again some "virtual" problem.

!!!! Please stop to send similar message to this group !!!!

This group is for serious programmers which need help or have some ideas to
improve OW.
You are writing that all your problems are caused by Open Watcom, even if it
is your user problems with absolute ignorance of documentation etc.
From now I will ignore you until you stop similar messages.

Jiri
Post by J
I have a structure in default-aligned space (no command line parameter etc)
and I don't know how much detail is required so this is a slightly more
complex example... it has a 64 bit value in a structure that followed 3
dword values... so it padded a dword before so the 64bit member was
aligned on a 64 bit boundary.
wpp386 did this
wcc386 did not do this
fairly sure watcom before 2.0 did not do this....
my fix is to reverse that and the next member so there's 4 dword values
before the the qword value
----------------------------
// I don't know if watcom falls under this...
#if defined( HAS_STDINT )
/* An unsigned integer type that is 64 bits long. */
typedef uint64_t _64;
#endif
typedef _64 THREAD_ID;
struct threads_tag
{
// these first two items MUST
// be declared publically, and MUST be visible
// to the thread created.
void* param;
void* (*proc)( struct threads_tag * );
void* (*simple_proc)( void* );
THREAD_ID thread_ident;
char * thread_event_name; // might be not a real thread.
};
----------------------------
J
2014-03-11 06:47:02 UTC
Permalink
Raw Message
Wow; I don't know what your issue is, or whatever... but anyway

I see, it's not reproducible in the simple case; I'm not sure what
interacts to cause it, I am usually more careful developing my test case...

It is reproducible in the real build

This is a screen shot of the local thread crash ( c++ compiled version of
same .c code ) and the original structure on the right it references;
notice the addresses are the same, all of the members up to thread_id are
correct, and there is no member inbetween the name and the proc.

(screenshot of debugger image)
https://drive.google.com/file/d/0B812EYiKwtkkV3pKeEdhZ0lUTVE

I did recently add the name; previously it would have had 2 dwords before
the ID instead of 3.

I can get sizeof( struct ) in the two that are different, and the address
of the members is not the same...

&***@global_timer_structure->pTimerThread->thread_ident =
0x0023:0x0016BE94
&thread->thread_ident = 0x0023:0x0016BE90

-------------
So; given that a clean compile generates the same crash (after reverting
the change to fix it); I will pursue what interaction does cause it.
J
2014-03-11 12:01:52 UTC
Permalink
Raw Message
Please do the same test, but also

#include <cinttype>

in the C++ code.

"cinttype" has a #include <pshpack8.h> without a #include <poppack.h>




------------- Code Clip -------
#ifdef __cplusplus
#include <cinttype>
#include <stdio>
#include <stdint>

#else
#include <stdio.h>
#include <stdint.h>

#endif

struct struct_tag
{
void (*proc)( struct struct_tag * );
void (*simple_proc)( void * );
char *name;
unsigned long long thread_ident;
};

#ifdef __cplusplus
extern "C"
#endif
int main( void )
{
struct struct_tag *instance = NULL;

printf( "size of struct = %d\n", sizeof( *instance ) );
printf( "%p %p\n", instance, &instance->thread_ident );
return 0;
}

----------V batch file V-----------

copy test.c test2.cpp

wcl386 test2.cpp
wcl386 test.c

---------V output V------------
M:\tmp\watcom\test_alignment_c_cpp>test.exe
size of struct = 24
00000000 00000010

M:\tmp\watcom\test_alignment_c_cpp>test2.exe
size of struct = 20
00000000 0000000c

------------------------------------------
Jiri Malak
2014-03-13 21:53:15 UTC
Permalink
Raw Message
Thanks for bug report.
If it is bug in OW v2 fork then you should use bug tracker on Sourceforge
site.
http://sourceforge.net/p/openwatcom/tickets/?source=navbar

It is fixed in git repository now.
New binary build will be available tomorrow.

Jiri
Post by J
Please do the same test, but also
#include <cinttype>
in the C++ code.
"cinttype" has a #include <pshpack8.h> without a #include <poppack.h>
------------- Code Clip -------
#ifdef __cplusplus
#include <cinttype>
#include <stdio>
#include <stdint>
#else
#include <stdio.h>
#include <stdint.h>
#endif
struct struct_tag
{
void (*proc)( struct struct_tag * );
void (*simple_proc)( void * );
char *name;
unsigned long long thread_ident;
};
#ifdef __cplusplus
extern "C"
#endif
int main( void )
{
struct struct_tag *instance = NULL;
printf( "size of struct = %d\n", sizeof( *instance ) );
printf( "%p %p\n", instance, &instance->thread_ident );
return 0;
}
----------V batch file V-----------
copy test.c test2.cpp
wcl386 test2.cpp
wcl386 test.c
---------V output V------------
M:\tmp\watcom\test_alignment_c_cpp>test.exe
size of struct = 24
00000000 00000010
M:\tmp\watcom\test_alignment_c_cpp>test2.exe
size of struct = 20
00000000 0000000c
------------------------------------------
Loading...