Stuck on passing struct to function

Hi, I seem to be having problems figuring out how to pass a struct to a function by reference.
I could use a little assistance since I’m still learning C.

This is a stripped down version of my code but all relevant info is here.


typedef struct
{
	char code1[16];
        double 	dRefAcc;               	/* Reference accumulation */ 
} config;

void main(void)
{
     config  UBconfigData;
     config *pUBconfig = &UBconfigData; // <-line 2288

     brdInit(); //<- line 2290
     ReadUB(pUBconfig); //<-line 2304
}

//-----------------------------------------------------------------------------
// Read UserBlock
/*** BeginHeader ReadUB */
xmem void ReadUB(struct config *pUBconfigData);
/*** EndHeader ***/

//nodebug
xmem void ReadUB(config *pUBconfigData)
{
   int Result;
   UINT16 UBlockSize;

   readUserBlock(&UBlockSize,500,2);//size of userblock data
   readUserBlock(pUBconfigData,502,UBlockSize);//read in UB configData

}

I get errors:
line 2288 : ERROR SC67V2.10X.C : Keyword ‘const’ can only be used with globals and static locals.
line 2290 : ERROR SC67V2.10X.C : Missing character ‘;’.
line 2304 : WARNING SC67V2.10X.C : Wrong type for parameter 1.

Any help figuring out my problem would be appreciated.

Thanks

Ron

You can’t initialize a non-constant variable on the same line as the declaration. This style of initialization can only be used with constants. Quite frankly, you have no need of this pointer variable anyway, see below.

typedef struct
{
   char code1[16];
   double 	dRefAcc;               	/* Reference accumulation */ 
} config;

void main(void)
{
     config  UBconfigData;

     brdInit();
     ReadUB(&UBconfigData);
}

//-----------------------------------------------------------------------
// Read UserBlock
/*** BeginHeader ReadUB */
xmem void ReadUB(config *pUBconfigData);
/*** EndHeader ***/

//nodebug
xmem void ReadUB(config *pUBconfigData)
{
   int Result;
   UINT16 UBlockSize;

   readUserBlock(&UBlockSize,500,2);//size of userblock data
   readUserBlock(pUBconfigData,502,UBlockSize);//read in UB configData
}

You may also notice the removal of struct before config in the ReadUB header. Once you typedef a structure, you no longer need the struct keyword to proceed the defined type, the type already contains it.

This is what I had originally started out with but when I compile I get:

line  400 : ERROR APPLIC.LIB   : ',' is missing/expected.               
line  400 : ERROR APPLIC.LIB   : Syntax error - or garbage at end of program.
line  400 : ERROR APPLIC.LIB   : Need function definition or declaration.
line  400 : ERROR APPLIC.LIB   : Expects ';'.                           
line  400 : ERROR APPLIC.LIB   : Old style function declaration missing parameter declaration list.
line  400 : ERROR APPLIC.LIB   : Missing character ')'.                 

//-----------------------------------------------------------------------------
// Read UserBlock
/*** BeginHeader ReadUB */
xmem void ReadUB(config *pUBconfigData);//<-Line 400
/*** EndHeader ***/

//nodebug
xmem void ReadUB(config *pUBconfigData)
{
   int Result;
   UINT16 UBlockSize;

   readUserBlock(&UBlockSize,500,2);//size of userblock data
   readUserBlock(pUBconfigData,502,UBlockSize);//read in UB configData
}

Ron

All of these errors have to do with what is on lines 1-399. Error reporting is not an exact science, you need to look before line 400, or post that here.

Yes I can understand that but when I comment out the ReadUB function the errors go away. So wouldn’t that mean it’s within the function?

Ron

The problem would be in your typedefs of either config or UINT16 then as everything else has proper syntax. If you can’t find it, could you post those typedefs.

Here is the entire config:


typedef struct
{
	char code1[16];
   double 	dRefAcc;               	/* Reference accumulation */
	double 	prop;		         	/* */
	double 	integ;		         	/* */
	UINT32 	maxCycleTime;    			/* Cycle Time */
	UINT32 	iRefAcc;                /*  */
	UINT32  iMainAcc;               /* Main accumulation */
	UINT32  iBatch1Acc;             /* Batch1 accumulation */
	UINT32  iBatch2Acc;             /* Batch2 accumulation */
	UINT32	avgcount;				/* flow weighted averaging parameter */
	UINT32 	maxWeight;   			/* Setpoint Weight for Closing Top Gate */
	UINT32 	minWeight;   			/* Setpoint Weight for Openning Top Gate */
	UINT32 	desflo;       			/* Desired Flowrate */
	UINT32 	loflo;        			/* Low Flow */
	UINT32 	hiflo;        			/* High Flow */
	UINT32 	target;       			/* Target Accumulation */
	UINT32 	pretarget;    			/* Pretarget accumulation */
	UINT32 	gopen;        			/* Gate Open in seconds */
	UINT32 	gclose;       			/* Gate Close */
	UINT32 	pulseWeight;         	/* pulse */
	UINT32 	pulseWidth;         	/* pulse */
   // UINT32  contrast;
    BYTE	iaddr[4];
    BYTE	maddr[4];
    BYTE	gaddr[4];
    BYTE	sotr;							/* Stop on Target Reached */
    UINT32   startFactor;     	// proportional factor for startup control
    BYTE Remote;						// = 2 use 4-20 Ma, =1 use AnyBus,   =0 use on-board ethernet
    BYTE StartMode;              //  2  = start & stop is network controlled
    										//  1 =  start & stop on single I/O point
    										// 0 = start & stop inputs are seperate
   UINT32 span420;				// flowrate setpoint for 20 ma input (MAXFLOW of old)
   char ScName[20];
   UINT32 cutoffaccum;          // MillView accumulator
   BYTE bLoc1;							//BYTE placeholders1-10
   BYTE bLoc2;
   BYTE bLoc3;
   BYTE bLoc4;
   BYTE bLoc5;
   BYTE bLoc6;
   BYTE bLoc7;
   BYTE bLoc8;
   BYTE bLoc9;
   BYTE bLoc10;
   UINT16 uLoc1;						//UINT16 placeholders1-10
   UINT16 uLoc2;
   UINT16 uLoc3;
   UINT16 uLoc4;
   UINT16 uLoc5;
   UINT16 uLoc6;
   UINT16 uLoc7;
   UINT16 uLoc8;
   UINT16 uLoc9;
   UINT16 uLoc10;
   UINT32 ULoc1;						//UINT32 placeholders1-10
   UINT32 ULoc2;
   UINT32 ULoc3;
   UINT32 ULoc4;
   UINT32 ULoc5;
   UINT32 ULoc6;
   UINT32 ULoc7;
   UINT32 ULoc8;
   UINT32 ULoc9;
   UINT32 ULoc10;
   double dLoc1;						//double placeholders1-4
   double dLoc2;
   double dLoc3;
   double dLoc4;

// code2 must always be the last element in the structure, add new elements above
    char code2[16];              	/* Scale Version Identification */
} config;

and the UNIT16:

typedef unsigned int  UINT16; 

Thanks for the help

Ron

It looks like the typedef for config is declared in a way that it is not in scope when the ReadUB function declaration is made. This would explain the ‘,’ is missing/expected error. If the typedef were not in scope, the parser would think config is a variable declaration, not a type for *pUBconfigData. Where do you declare the typedef of config?

If after a /*** BeginHeader func / of some other function, it may not be in scope. Look at some of our pre-defined libraries and you will see global constants and typedefs are put in their own
/
** BeginHeader /

/
** EndHeader */
block not related to any specific function to insure they are always included when the library is used.

That make absolute sense!

The typedef is in the main C file and the ReadUb is in a lib.

I encapsulated the config typedef in BEGIN/END headers.

The declaration of config configData is a global so I never thought about the typedef not being global.

Unfortunately I still get the same errors when I try to compile.

/*** BeginHeader  ********************************************/
typedef struct
{
	char code1[16];
   double 	dRefAcc;               	/* Reference accumulation */
	double 	prop;		         	/* */
	double 	integ;		         	/* */
	UINT32 	maxCycleTime;    			/* Cycle Time */
	UINT32 	iRefAcc;                /*  */
	UINT32  iMainAcc;               /* Main accumulation */
	UINT32  iBatch1Acc;             /* Batch1 accumulation */
	UINT32  iBatch2Acc;             /* Batch2 accumulation */
	UINT32	avgcount;				/* flow weighted averaging parameter */
	UINT32 	maxWeight;   			/* Setpoint Weight for Closing Top Gate */
	UINT32 	minWeight;   			/* Setpoint Weight for Openning Top Gate */
	UINT32 	desflo;       			/* Desired Flowrate */
	UINT32 	loflo;        			/* Low Flow */
	UINT32 	hiflo;        			/* High Flow */
	UINT32 	target;       			/* Target Accumulation */
	UINT32 	pretarget;    			/* Pretarget accumulation */
	UINT32 	gopen;        			/* Gate Open in seconds */
	UINT32 	gclose;       			/* Gate Close */
	UINT32 	pulseWeight;         	/* pulse */
	UINT32 	pulseWidth;         	/* pulse */
   // UINT32  contrast;
    BYTE	iaddr[4];
    BYTE	maddr[4];
    BYTE	gaddr[4];
    BYTE	sotr;							/* Stop on Target Reached */
    UINT32   startFactor;     	// proportional factor for startup control
    BYTE Remote;						// = 2 use 4-20 Ma, =1 use AnyBus,   =0 use on-board ethernet
    BYTE StartMode;              //  2  = start & stop is network controlled
    										//  1 =  start & stop on single I/O point
    										// 0 = start & stop inputs are seperate
   UINT32 span420;				// flowrate setpoint for 20 ma input (MAXFLOW of old)
   char ScName[20];
   UINT32 cutoffaccum;          // MillView accumulator
   BYTE bLoc1;							//BYTE placeholders1-10
   BYTE bLoc2;
   BYTE bLoc3;
   BYTE bLoc4;
   BYTE bLoc5;
   BYTE bLoc6;
   BYTE bLoc7;
   BYTE bLoc8;
   BYTE bLoc9;
   BYTE bLoc10;
   UINT16 uLoc1;						//UINT16 placeholders1-10
   UINT16 uLoc2;
   UINT16 uLoc3;
   UINT16 uLoc4;
   UINT16 uLoc5;
   UINT16 uLoc6;
   UINT16 uLoc7;
   UINT16 uLoc8;
   UINT16 uLoc9;
   UINT16 uLoc10;
   UINT32 ULoc1;						//UINT32 placeholders1-10
   UINT32 ULoc2;
   UINT32 ULoc3;
   UINT32 ULoc4;
   UINT32 ULoc5;
   UINT32 ULoc6;
   UINT32 ULoc7;
   UINT32 ULoc8;
   UINT32 ULoc9;
   UINT32 ULoc10;
   double dLoc1;						//double placeholders1-4
   double dLoc2;
   double dLoc3;
   double dLoc4;

// code2 must always be the last element in the structure, add new elements above
    char code2[16];              	/* Scale Version Identification */
} config;

/*** EndHeader ***********************************************/

Ron

It sounds like you added the begin/end headers within the main C file. You must move the typedef of config to the beginning of the library file, not the C file. A library file should generally not be dependent on declarations in C files to compile correctly. The whole purpose of a library file is to support code re-use, so if a library function is using a structure, the typedef should either be in the library, or in a library that it specifically uses, not in the C file. There may be a few exceptions, but generally this rule should be followed. If you must leave it in the C file, make sure it is declared BEFORE you #use the library file.

That did the trick, I moved the typedef above the #use and it compiled just fine. I will move it to a lib file once I figure out a few things.

thanks for your help

Ron