Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 16, 2001 Union bug?? | ||||
---|---|---|---|---|
| ||||
It's possible that I've uncovered a bug in the C compiler. The complicated structure below includes a union of subsidiary structure types. Given two of these ParseBlock structures, I want to copy one of the unionized subsidiaries from one ParseBlock to the other. It is turning out to be surprisingly close to impossible, and I don't understand why. This should be a simple memory operation. The structures are declared as __far in my 16-bit Windows 3.1 app. The union is a union of structures which are defined in a vendor header file. These are identified as SPM_XXX structs. The only code that works copies the entire ParseBlock, including the internal union. (Here outpb and inpb are far pointers to ParseBlock.) *outpb = *inpb; The following similar code does not work (but should): *((SPM_APPROACH_PARAMS __far *) &(outpb->structs.pb_SPM_APPROACH_PARAMS)) = *((SPM_APPROACH_PARAMS __far *) &(inpb->structs.pb_SPM_APPROACH_PARAMS)); The more natural and expected fmemcpy() also fails: _fmemcpy(&(outpb->structs.pb_SPM_APPROACH_PARAMS), &(inpb->structs.pb_SPM_APPROACH_PARAMS), sizeof(SPM_APPROACH_PARAMS)); Does anyone have a clue what is going on? Mark typedef struct { // locking flag and stack to indicate how it was // populated BOOL locked; // general atomic parameter storage unsigned long int U32[k_PARSE_PARAM_ARRAY_SZ]; unsigned short int U16[k_PARSE_PARAM_ARRAY_SZ]; signed long int I32[k_PARSE_PARAM_ARRAY_SZ]; signed short int I16[k_PARSE_PARAM_ARRAY_SZ]; float SGL[k_PARSE_PARAM_ARRAY_SZ]; double DBL[k_PARSE_PARAM_ARRAY_SZ]; char BLC[k_PARSE_PARAM_ARRAY_SZ]; HSPM spmHandles[k_PARSE_PARAM_ARRAY_SMALL_SZ]; SPMERROR spmErrs[k_PARSE_PARAM_ARRAY_SMALL_SZ]; HWND window[k_PARSE_PARAM_ARRAY_SMALL_SZ]; char __far STR[k_PARSE_PARAM_ARRAY_SMALL_SZ][k_PARSE_STRING_SZ]; // next-free (also population count) signed long int U32_slot,U16_slot,I32_slot,I16_slot, SGL_slot,DBL_slot,spmHandles_slot,spmErrs_slot, window_slot,BLC_slot,STR_slot; // output counters signed long int U32_outcnt,U16_outcnt,I32_outcnt,I16_outcnt, SGL_outcnt,DBL_outcnt,spmHandles_outcnt,spmErrs_outcnt, window_outcnt,BLC_outcnt,STR_outcnt; // Arrays // Can be any dimension, data is contiguous, row-major order (C order) long int arrayDimensionality; // 1D, 2D, 3D, ... unsigned long int arrayDims; // the actual array sizes TypeCode arrayType; union arrays { unsigned long int __huge * U32Ptr; unsigned short int __huge * U16Ptr; signed long int __huge * I32Ptr; signed short int __huge * I16Ptr; float __huge * SGLPtr; double __huge * DBLPtr; }; // storage for pointers to structs for recursion TypeCode recursionStack[k_PARSE_PARAM_ARRAY_SZ]; unsigned long int recursion; // Every struct type in spm.h, the Park API TypeCode structType; union { SPM_PARAMS pb_SPM_PARAMS; SPM_STATUS_ITEM pb_SPM_STATUS_ITEM; SPM_CALIBRATE_PROGRESS pb_SPM_CALIBRATE_PROGRESS; SPM_ERROR_SIGNAL pb_SPM_ERROR_SIGNAL; SPM_SCANNER_Z pb_SPM_SCANNER_Z; SPM_SCANNER_XY pb_SPM_SCANNER_XY; SPM_SCANNER_Z_SLOPE pb_SPM_SCANNER_Z_SLOPE; SPM_BIAS pb_SPM_BIAS; SPM_DATA_FILTER_PARAMS pb_SPM_DATA_FILTER_PARAMS; SPM_STEP_PIECE pb_SPM_STEP_PIECE; SPM_WAVE_PIECE pb_SPM_WAVE_PIECE; SPM_WAVE_ACQ pb_SPM_WAVE_ACQ; SPM_SCANNING_PARAMS pb_SPM_SCANNING_PARAMS; SPM_SCAN_RATE_PARAMS pb_SPM_SCAN_RATE_PARAMS; SPM_APPROACH_PARAMS pb_SPM_APPROACH_PARAMS; SPM_APPROACH_PARAMS_LOW pb_SPM_APPROACH_PARAMS_LOW; SPM_MOVE_STEPPER_PARAMS pb_SPM_MOVE_STEPPER_PARAMS; SPM_STEPPER_PARAMS pb_SPM_STEPPER_PARAMS; SPM_MOVE_IMOTOR_PARAMS pb_SPM_MOVE_IMOTOR_PARAMS; SPM_MOVE_PC38_PARAMS pb_SPM_MOVE_PC38_PARAMS; SPM_NCM_SWEEP_LOW_TYPE pb_SPM_NCM_SWEEP_LOW_TYPE; SPM_NCM_PHOP_TYPE pb_SPM_NCM_PHOP_TYPE; SPM_NCM_RESPONSE_LUT pb_SPM_NCM_RESPONSE_LUT; SPM_VOLTAGE_PROBE_PARAMS pb_SPM_VOLTAGE_PROBE_PARAMS; SPM_NCM_SWEEP_PARAMS pb_SPM_NCM_SWEEP_PARAMS; SPM_NCM_SWEEP_POINT pb_SPM_NCM_SWEEP_POINT; } structs; } ParseBlock, __far * ParseBlockPtr; |
May 16, 2001 Re: Union bug?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | I may have discovered the problem. ParseBlock __far inpb_block, outpb_block; declares one of the structs as far, the other near. This was a mistake. Mark |
May 16, 2001 Re: Union bug?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans |
Still I would like to understand why the assignment *outpb = *inpb works when one block is declared near, the other far. And what is the doctor-recommended method for copying between near and far data segments. And how would I assign two far objects to the same data segment. I did not find a pragma for this purpose.
I tried chaning both to __far and some other code broke mysteriously. Oh how I love 16-bit code.
Mark
On Wed, 16 May 2001 21:26:39 GMT, Mark Evans <mevans@zyvex.com> wrote:
> I may have discovered the problem.
>
> ParseBlock __far inpb_block, outpb_block;
>
> declares one of the structs as far, the other near. This was a mistake.
>
> Mark
>
>
|
May 17, 2001 Re: Union bug?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | It all depends on your memory model. I'd use _fmemcpy() if in a near data model, and memcpy() in a far data model. "Mark Evans" <mevans@zyvex.com> wrote in message news:1106_990055289@evans... > > Still I would like to understand why the assignment *outpb = *inpb works when one block is declared near, the other far. And what is the doctor-recommended method for copying between > near and far data segments. And how would I assign two far objects to the same data segment. I did not find a pragma for this purpose. > > I tried chaning both to __far and some other code broke mysteriously. Oh how I love 16-bit code. > > Mark > > > > On Wed, 16 May 2001 21:26:39 GMT, Mark Evans <mevans@zyvex.com> wrote: > > I may have discovered the problem. > > > > ParseBlock __far inpb_block, outpb_block; > > > > declares one of the structs as far, the other near. This was a mistake. > > > > Mark > > > > > > |
May 17, 2001 Re: Union bug?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter,
I've tried both actually, and both fail.
This is very mysterious to me why a deref assignment works and the runtime calls don't.
Mark
On Wed, 16 May 2001 17:29:59 -0700, "Walter" <walter@digitalmars.com> wrote:
> It all depends on your memory model. I'd use _fmemcpy() if in a near data
> model, and memcpy() in a far data model.
>
>
> "Mark Evans" <mevans@zyvex.com> wrote in message news:1106_990055289@evans...
> >
> > Still I would like to understand why the assignment *outpb = *inpb works
> when one block is declared near, the other far. And what is the doctor-recommended method for copying between
> > near and far data segments. And how would I assign two far objects to the
> same data segment. I did not find a pragma for this purpose.
> >
> > I tried chaning both to __far and some other code broke mysteriously. Oh
> how I love 16-bit code.
> >
> > Mark
> >
> >
> >
> > On Wed, 16 May 2001 21:26:39 GMT, Mark Evans <mevans@zyvex.com> wrote:
> > > I may have discovered the problem.
> > >
> > > ParseBlock __far inpb_block, outpb_block;
> > >
> > > declares one of the structs as far, the other near. This was a mistake.
> > >
> > > Mark
> > >
> > >
> >
> >
>
>
|
May 17, 2001 Re: Union bug?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter, I still suspect something is wrong with putting structures inside a union. Referring to the previous post, this failure is interesting: SPM_APPROACH_PARAMS __far * src; SPM_APPROACH_PARAMS __far * dest; src = &((inpb->structs).pb_SPM_APPROACH_PARAMS); dest = &((outpb->structs).pb_SPM_APPROACH_PARAMS); *dest = *src; // fails /*Approach Params from a header file*/ typedef struct { BOOL bQuery; BOOL bLift; BOOL bAutoLift; BOOL bScannerXY; BOOL bReNull; BOOL bApproach; BOOL bSanityChecks; long nRetry; BOOL bSelectStyle; BOOL bCrash; BOOL bSelectMotor; BOOL bFineMotor; long nZMotorOptions; float fLiftMicrons; float fRetryMicrons; float fLiftSpeed; float fCrashSpeed; BOOL bOvershootMicrons; float fOvershootMicrons; BOOL bScannerZThreshold; float fScannerZThreshold; short nScannerZUnit; float fTimeoutSeconds; float fScannerMicronsX; float fScannerMicronsY; BOOL bESigCal; float fESigCalFactor; } SPM_APPROACH_PARAMS; |
May 17, 2001 Re: Union bug?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | Are you using C or C++? It makes a difference.
"Mark Evans" <mevans@zyvex.com> wrote in message news:1108_990060635@evans...
> Walter,
>
> I still suspect something is wrong with putting structures inside a union. Referring to the previous post, this failure is interesting:
>
>
> SPM_APPROACH_PARAMS __far * src;
> SPM_APPROACH_PARAMS __far * dest;
>
> src = &((inpb->structs).pb_SPM_APPROACH_PARAMS);
> dest = &((outpb->structs).pb_SPM_APPROACH_PARAMS);
>
> *dest = *src; // fails
>
>
> /*Approach Params from a header file*/
> typedef struct
> {
> BOOL bQuery;
> BOOL bLift;
> BOOL bAutoLift;
> BOOL bScannerXY;
> BOOL bReNull;
> BOOL bApproach;
> BOOL bSanityChecks;
> long nRetry;
> BOOL bSelectStyle;
> BOOL bCrash;
> BOOL bSelectMotor;
> BOOL bFineMotor;
> long nZMotorOptions;
> float fLiftMicrons;
> float fRetryMicrons;
> float fLiftSpeed;
> float fCrashSpeed;
> BOOL bOvershootMicrons;
> float fOvershootMicrons;
> BOOL bScannerZThreshold;
> float fScannerZThreshold;
> short nScannerZUnit;
> float fTimeoutSeconds;
> float fScannerMicronsX;
> float fScannerMicronsY;
> BOOL bESigCal;
> float fESigCalFactor;
> } SPM_APPROACH_PARAMS;
>
>
|
May 17, 2001 Re: Union bug?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Plain vanilla C with no trace of C++. My build flags are SCFLAGS = -D_WINIO=1 -D_parkplug -mluw -Jm -p -r -WA -S -5 -a2 -IC:\DigMars\dm\include\;C:\DigMars\dm\include\win16;..\Snippets and all files end in .c or .h. The syntax below is legitimate C that should work. All I can figure is that some kind of segmentation issue is interfering with this simple memory copy. Mark On Wed, 16 May 2001 19:07:40 -0700, "Walter" <walter@digitalmars.com> wrote: > Are you using C or C++? It makes a difference. > > "Mark Evans" <mevans@zyvex.com> wrote in message news:1108_990060635@evans... > > Walter, > > > > I still suspect something is wrong with putting structures inside a union. Referring to the previous post, this failure is interesting: > > > > > > SPM_APPROACH_PARAMS __far * src; > > SPM_APPROACH_PARAMS __far * dest; > > > > src = &((inpb->structs).pb_SPM_APPROACH_PARAMS); > > dest = &((outpb->structs).pb_SPM_APPROACH_PARAMS); > > > > *dest = *src; // fails > > > > > > /*Approach Params from a header file*/ > > typedef struct > > { > > BOOL bQuery; > > BOOL bLift; > > BOOL bAutoLift; > > BOOL bScannerXY; > > BOOL bReNull; > > BOOL bApproach; > > BOOL bSanityChecks; > > long nRetry; > > BOOL bSelectStyle; > > BOOL bCrash; > > BOOL bSelectMotor; > > BOOL bFineMotor; > > long nZMotorOptions; > > float fLiftMicrons; > > float fRetryMicrons; > > float fLiftSpeed; > > float fCrashSpeed; > > BOOL bOvershootMicrons; > > float fOvershootMicrons; > > BOOL bScannerZThreshold; > > float fScannerZThreshold; > > short nScannerZUnit; > > float fTimeoutSeconds; > > float fScannerMicronsX; > > float fScannerMicronsY; > > BOOL bESigCal; > > float fESigCalFactor; > > } SPM_APPROACH_PARAMS; > > > > > > |
May 17, 2001 Re: Union bug?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter, Think I found my bug. I did a simple test to validate memory copying with * and it works. I had been assuming correct operation of another module which was incomplete and because of that, not referencing the actual data copied. Mark |
May 17, 2001 Re: Union bug?? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mark Evans | I'm glad you found the problem and are able to proceed. -Walter "Mark Evans" <mevans@zyvex.com> wrote in message news:1104_990119091@evans... > Walter, > > Think I found my bug. I did a simple test to validate memory copying with * and it works. > > I had been assuming correct operation of another module which was incomplete and because of that, not referencing the actual data copied. > > Mark > > |
Copyright © 1999-2021 by the D Language Foundation