Jump to content


Photo

Function Pointers In A Structure


7 replies to this topic

#1 Tony

Tony

    Newbrie

  • EstablishedMember
  • 5 posts
  • Gender:Male
  • Location:Christchurch, New Zealand

Posted 18 August 2011 - 09:33 AM

Hi -

I am running an older version of BoostC (v.6.81) as this is what my work has purchased. I am trying to add a function pointer to a structure but the compiler gives a "Missing right brace" error. As far as I can see there is nothing wrong with the code. Is this a limitation with this version of the compiler? The manual says "pointers can be used in the standard way". The code below is situated in a header file.

typedef struct cmd_S
{
void ( *cmdFunc )( char * cmdLinePt );
char cmdStr[ CMD_STR_MAX_LEN ];
} cmdStruct;

Cheers,
Tony.

#2 Dave

Dave

    Super Maniac

  • Administrators
  • PipPipPipPipPip
  • 2,091 posts
  • Gender:Male
  • Location:UK
  • Interests:How things work, Electronics, Software, Cycling.

Posted 19 August 2011 - 08:14 AM

Tony,

Hi -

I am running an older version of BoostC (v.6.81) as this is what my work has purchased. I am trying to add a function pointer to a structure but the compiler gives a "Missing right brace" error. As far as I can see there is nothing wrong with the code. Is this a limitation with this version of the compiler? The manual says "pointers can be used in the standard way". The code below is situated in a header file.

typedef struct cmd_S
{
void ( *cmdFunc )( char * cmdLinePt );
char cmdStr[ CMD_STR_MAX_LEN ];
} cmdStruct;

You have probably done made the same mistake I did when trying to compile your code:

#define CMD_STR_MAX_LEN 1;


typedef struct cmd_S
{
	void	( *cmdFunc )( char * cmdLinePt );
	char	cmdStr[ CMD_STR_MAX_LEN ];
	
} cmdStruct;

void main()
{
}

Notice the mistake?
There is a semi colon where it shouldn't be, at the end of "#define CMD_STR_MAX_LEN 1;".

Removing that allows successful compilation for me.

Regards
Dave

#3 Tony

Tony

    Newbrie

  • EstablishedMember
  • 5 posts
  • Gender:Male
  • Location:Christchurch, New Zealand

Posted 23 August 2011 - 10:39 AM

Tony,

Hi -

I am running an older version of BoostC (v.6.81) as this is what my work has purchased. I am trying to add a function pointer to a structure but the compiler gives a "Missing right brace" error. As far as I can see there is nothing wrong with the code. Is this a limitation with this version of the compiler? The manual says "pointers can be used in the standard way". The code below is situated in a header file.

typedef struct cmd_S
{
void ( *cmdFunc )( char * cmdLinePt );
char cmdStr[ CMD_STR_MAX_LEN ];
} cmdStruct;

You have probably done made the same mistake I did when trying to compile your code:

#define CMD_STR_MAX_LEN 1;


typedef struct cmd_S
{
	void	( *cmdFunc )( char * cmdLinePt );
	char	cmdStr[ CMD_STR_MAX_LEN ];
	
} cmdStruct;

void main()
{
}

Notice the mistake?
There is a semi colon where it shouldn't be, at the end of "#define CMD_STR_MAX_LEN 1;".

Removing that allows successful compilation for me.

Regards
Dave

Hi Dave -

Thanks for your reply. It turns out that this wasn't the problem (although I did remove it thanks :( ) because if I comment out the function pointer line in the structure then it compiles fine. I ended up fixing this by upgrading my compiler to version 6.97. This now compiles but has revealed another issue. Code snippets are below, full project is attached.

In header:
typedef struct cmd_S
{
	char		cmdStr[ CMD_STR_MAX_LEN ];
	void		( *cmdFunc )( char * cmdLinePt );
} cmdStruct;

In C file:
cmdStruct commands[ CMD_NUM ] =
{
	{ "\1load", cmdLoad },
	{ "\1run", cmdRun },
	{ "\1stop", cmdStop },
	{ "\1dump", cmdDump },
	{ "\1clear", cmdClear },
	{ "\1erase", cmdErase },
	{ "\2blank", cmdBlank },
	{ "\2burn", cmdBurn },
	{ "\1verify", cmdVerify }
};

//-----------

cmdStruct *
getCmd( char ** cmdLinePtPt )
{
//--------
return &commands[ i ];
}

void main( void )
{
cmdStruct	*	command;

//---------
command = getCmd( &cmdBuffPt );
			
if ( command != NULL )
{
	( *command->cmdFunc )( cmdBuffPt );
}
}

The last line above produces an "error: missing semicolon" error.

If this line is commented out the code compiles, but produces the following warnings:

Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x10000BBD
Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x10000BBD
Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x10000F9D
Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x10000F9D
Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x100010F1
Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x100010F1
Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x100012B6
Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x100012B6

I have attached my project snapshot if you need it; the AROStdTypes.h should be placed in the 'include' folder. There must be something fundamentally wrong with the way I am trying to do function pointers.

Functionally, the user enters a command into main, getCmd then searches the commands array for the command string and returns the address of the array element found. The main function then calls the returned command function via the pointer stored in the array. At least this is what's supposed to happen!

Cheers,
Tony O'Brien.

Attached Files



#4 Dave

Dave

    Super Maniac

  • Administrators
  • PipPipPipPipPip
  • 2,091 posts
  • Gender:Male
  • Location:UK
  • Interests:How things work, Electronics, Software, Cycling.

Posted 24 August 2011 - 07:50 PM

Tony,

I have attached my project snapshot if you need it; the AROStdTypes.h should be placed in the 'include' folder. There must be something fundamentally wrong with the way I am trying to do function pointers.

Functionally, the user enters a command into main, getCmd then searches the commands array for the command string and returns the address of the array element found. The main function then calls the returned command function via the pointer stored in the array. At least this is what's supposed to happen!

Cheers,
Tony O'Brien.

Drop the brackets when using the function pointer, see below:

#define CMD_STR_MAX_LEN 10
#define CMD_NUM 10
#define NULL 0

typedef struct cmd_S
{
	char		cmdStr[ CMD_STR_MAX_LEN ];
	void		( *cmdFunc )( char * cmdLinePt );
} cmdStruct;

void cmdLoad( char* cmdLine )
{
}

void cmdRun( char* cmdLine )
{
}

void cmdStop( char* cmdLine )
{
}

cmdStruct commands[ CMD_NUM ] =
{
	{ "\1load", cmdLoad },
	{ "\1run", cmdRun },
	{ "\1stop", cmdStop },
};



void		( *cmdFunc )(); 

//-----------
char* str = "1234567890";
cmdStruct* getCmd( char ** cmdLinePtPt )
{
	//--------
	int i = 1;
	*cmdLinePtPt = str;
	return &commands[ i ];
}

void main( void )
{
	cmdStruct* command;
	char* cmdBuffPt = NULL;
	
	//---------
	command = getCmd( &cmdBuffPt );
				
	if ( command != NULL )
	{
		command->cmdFunc( cmdBuffPt );
	}
	
	while(1);
}

Regards
Dave

#5 Tony

Tony

    Newbrie

  • EstablishedMember
  • 5 posts
  • Gender:Male
  • Location:Christchurch, New Zealand

Posted 25 August 2011 - 11:20 PM

Tony,

Drop the brackets when using the function pointer, see below:

Regards
Dave



Hi Dave -

Thanks again for your help. Dropping the brackets made my code compile, although this is not how K & R describe using function pointers. I'm still getting the warnings mentioned before, though,
"Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x10000BBD"
and looking at the assembler generated I am not confident the correct values are being written into the array for the function pointers. I can see the ASCII for the strings and the string terminator followed by a single byte that increases in value (from 0x01) for each entry in the array. Any idea what might be causing this, or at least, what it means?

Cheers,
Tony.

#6 Dave

Dave

    Super Maniac

  • Administrators
  • PipPipPipPipPip
  • 2,091 posts
  • Gender:Male
  • Location:UK
  • Interests:How things work, Electronics, Software, Cycling.

Posted 28 August 2011 - 10:20 AM

Thanks again for your help. Dropping the brackets made my code compile, although this is not how K & R describe using function pointers.

You are correct, accepted syntax doesn't appear to be as one would expect, I've added it to our bug list to get fixed.

I'm still getting the warnings mentioned before, though,
"Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x10000BBD"

You can ignore this warning. It just means that the debug file (coff file) can't represent the function pointer data type. All this means is that you won't be able to watch the pointer values in the debugger.

and looking at the assembler generated I am not confident the correct values are being written into the array for the function pointers. I can see the ASCII for the strings and the string terminator followed by a single byte that increases in value (from 0x01) for each entry in the array. Any idea what might be causing this, or at least, what it means?

The way function pointers are implemented in BoostC is that the function pointer has a simple value, that value is an index into a jump table where the function arguments are patched, then the actual function is called. On return the return value is patched up and then the code returns to the caller. So what you see for each function pointer being a number that start at 1 and increases is what would you should get.

Regards
Dave

#7 Tony

Tony

    Newbrie

  • EstablishedMember
  • 5 posts
  • Gender:Male
  • Location:Christchurch, New Zealand

Posted 29 August 2011 - 08:37 AM

Thanks again for your help. Dropping the brackets made my code compile, although this is not how K & R describe using function pointers.

You are correct, accepted syntax doesn't appear to be as one would expect, I've added it to our bug list to get fixed.

I'm still getting the warnings mentioned before, though,
"Coff generation: Internal Warning: Member Var:cmdFunc Unrecognised type id:0x10000BBD"

You can ignore this warning. It just means that the debug file (coff file) can't represent the function pointer data type. All this means is that you won't be able to watch the pointer values in the debugger.

and looking at the assembler generated I am not confident the correct values are being written into the array for the function pointers. I can see the ASCII for the strings and the string terminator followed by a single byte that increases in value (from 0x01) for each entry in the array. Any idea what might be causing this, or at least, what it means?

The way function pointers are implemented in BoostC is that the function pointer has a simple value, that value is an index into a jump table where the function arguments are patched, then the actual function is called. On return the return value is patched up and then the code returns to the caller. So what you see for each function pointer being a number that start at 1 and increases is what would you should get.

Regards
Dave

Hi Dave -

Excellent explanation, thanks Dave. I'll let you know how it goes once I get it loaded onto a target.

Cheers,
Tony.

#8 RobertBeic

RobertBeic

    Newbrie

  • Members
  • 1 posts
  • Gender:Male
  • Location:143040
  • Interests:RobertBeicLY

Posted 07 August 2016 - 01:10 PM

I have a rough concept of being able to return a variable length array of pointers allocated by calloc with the data also allocated by calloc where the pointer list ends with NULL. So a could traverse the data and stop when it hits null, just like a string. But Im not 100 on how to dealloc the array of data yet, dealloc on the array of pointers 1 with last member = NULL seems easy enough. I guess maybe I could calloc each member of the array of data and use the pointer array to pass the right memory address to free. Then write a function to possible conveniently wrap this using type void and passing size_t. Then possibly wrapping the entire calloc bit into a similar type void function to easy the actual return of data. This seems obvious enough that I feel it has been done before. This is just a morph of the concept of returning a malloc allocated null-terminated string. The reason I want to do this is to be able to possibly return a set of matching points for geometry functions, where the number of points vertices maybe be anything from 0 matches to N matches. Will have to write and test this, but Im rather sure I can make this work. I do not like the idea I cannot return an array of unknown size in C. /End rant ...



Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users