Pointers to functions

M

Mr John FO Evans

Hi

Have already used function pointers to a simple subroutine ie

typedef void (*FPOINT)(void)
void func(void)
typedef struct
{
FPOINT func;
....
} name;

However when I try to do the same with:-

double func(int a, double b.....etc);

I get into a mess when I wish to equivalence two functions with:-

typedef union
{
FPOINT funca;
FPOINT funcb;
}joint;

even when I use
typedef double (*FPOINT)(inta, double b......)

Can anyone help a novice function pointer man!!

John
 
M

Michael Mair

Mr said:
Hi

Have already used function pointers to a simple subroutine ie

typedef void (*FPOINT)(void)
void func(void)
typedef struct
{
FPOINT func;
....
} name;

However when I try to do the same with:-

double func(int a, double b.....etc);

I get into a mess when I wish to equivalence two functions with:-

typedef union
{
FPOINT funca;
FPOINT funcb;
}joint;

A union most of the time is used to collect equivalently used
mutually exclusive members of different type.
You probably want
typedef union {
FPOINT funca;
FPOINT2 funcb;
}
where FPOINT2 is a different function pointer type.
even when I use
typedef double (*FPOINT)(inta, double b......)

Use
typedef double (*FPOINT2) (int, double, ....);

You still have the problem of determining when to use funca
and when to use funcb.

A recent thread starting at
<[email protected]>
discusses some dos and donts and alternatives to the above
union.

Cheers
Michael
 
B

Barry Schwarz

Hi

Have already used function pointers to a simple subroutine ie

typedef void (*FPOINT)(void)
void func(void)
typedef struct
{
FPOINT func;
....
} name;

However when I try to do the same with:-

double func(int a, double b.....etc);
The type FPOINT describes a pointer to a function which accepts no
arguments and does not return anything. An object of this type should
never hold the address of a function of any other type. Your new
function returns a double and accepts arguments. The address of this
function should NOT be stored in an object of type FPOINT.


Remove del for email
 
S

santosh

Mr said:
Hi

Have already used function pointers to a simple subroutine ie

typedef void (*FPOINT)(void)
void func(void)
typedef struct
{
FPOINT func;
....
} name;

However when I try to do the same with:-

double func(int a, double b.....etc);

I get into a mess when I wish to equivalence two functions with:-

typedef union
{
FPOINT funca;
FPOINT funcb;
}joint;

even when I use
typedef double (*FPOINT)(inta, double b......)

FPOINT is already typedef'ed as a pointer to a function. Then you're
coercing it to act as a pointer to a function of a different signature.
Calling the function will invoke undefined behaviour. Instead declare
another type to point to the second function.
 
K

Keith Thompson

Mr John FO Evans said:
Have already used function pointers to a simple subroutine ie

typedef void (*FPOINT)(void)
void func(void)
typedef struct
{
FPOINT func;
....
} name;

However when I try to do the same with:-

double func(int a, double b.....etc);

I get into a mess when I wish to equivalence two functions with:-

typedef union
{
FPOINT funca;
FPOINT funcb;
}joint;

even when I use
typedef double (*FPOINT)(inta, double b......)

Can anyone help a novice function pointer man!!

What exactly are you trying to accomplish? Please explain without
trying to use "equivalence" as a verb. Verbing nouns isn't
necessarily a bad thing; I just don't know what you mean.

Why are you using a union? If you expect to be able to store a value
in one member of a union and then use the other one, you're probably
doing something wrong. You need to keep track of which member is
currently valid (only one at a time can be), unless you're
deliberately doing some very low-level and non-portable stuff.

A good start would be to show us some actual code. Don't use "..."
unless it's actually part of the function declaration.
 
D

Default User

Mr John FO Evans wrote:

I get into a mess when I wish to equivalence two functions with:-

typedef union
{
FPOINT funca;
FPOINT funcb;
}joint;

What are you trying to accomplish, what problem are you solving? Your
approach, as the others have pointed out, is fundamentally flawed. I
can't really grasp WHY you want to do this. Explain your goal as well
as your broken solutions in these cases. Very likely the true answer
lies elsewhere.



Brian
 
M

Mr John FO Evans

[QUOTE="Keith Thompson said:
However when I try to do the same with:-

double func(int a, double b.....etc);

I get into a mess when I wish to equivalence two functions with:-

typedef union
{
FPOINT funca;
FPOINT funcb;
}joint;

even when I use
typedef double (*FPOINT)(inta, double b......)

Can anyone help a novice function pointer man!!

What exactly are you trying to accomplish? Please explain without
trying to use "equivalence" as a verb. Verbing nouns isn't
necessarily a bad thing; I just don't know what you mean.

Why are you using a union? If you expect to be able to store a value
in one member of a union and then use the other one, you're probably
doing something wrong. You need to keep track of which member is
currently valid (only one at a time can be), unless you're
deliberately doing some very low-level and non-portable stuff.
[/QUOTE]
I was attempting to allow a function to have effectively two entry points
(easy in assembler) so that it could be called from either. I also need to
disable one entry point or switch entry points using a compiler directive.

The current code (which is fine) is:-

double funca(<args>) /* args is always the same */
{
'''''
return <double>;
}

#if NOT_EMBEDDED
double func(<args>)
{
return funca(<args>);
}
#endif

If a number of code fragments as above are embedded in a single task that task
can call funca (or funcb etc). The Linker requires that the unused entry point
func (which will be in every fragment) is disabled in this case.

Alternatively each function may be embedded in a single task - in which case the
call to the function always needs to be func. In this case I was hoping to avoid
the double call with a (long) argument string by using some form of equivalence
or a function pointer.

NB the value of NOT_EMBEDDED is set in the call to the compiler (Norcroft)

NNB I apologise if my terminology is a bit shaky. In this case task means
a separate program.


John
 
E

Eric Sosman

Mr John FO Evans wrote On 03/25/06 18:18,:
[QUOTE="Keith Thompson said:
However when I try to do the same with:-

double func(int a, double b.....etc);

I get into a mess when I wish to equivalence two functions with:-

typedef union
{
FPOINT funca;
FPOINT funcb;
}joint;

even when I use
typedef double (*FPOINT)(inta, double b......)

Can anyone help a novice function pointer man!!

What exactly are you trying to accomplish? Please explain without
trying to use "equivalence" as a verb. Verbing nouns isn't
necessarily a bad thing; I just don't know what you mean.

Why are you using a union? If you expect to be able to store a value
in one member of a union and then use the other one, you're probably
doing something wrong. You need to keep track of which member is
currently valid (only one at a time can be), unless you're
deliberately doing some very low-level and non-portable stuff.

I was attempting to allow a function to have effectively two entry points
(easy in assembler) so that it could be called from either. I also need to
disable one entry point or switch entry points using a compiler directive.

The current code (which is fine) is:-

double funca(<args>) /* args is always the same */
{
'''''
return <double>;
}

#if NOT_EMBEDDED
double func(<args>)
{
return funca(<args>);
}
#endif

If a number of code fragments as above are embedded in a single task that task
can call funca (or funcb etc). The Linker requires that the unused entry point
func (which will be in every fragment) is disabled in this case.

Alternatively each function may be embedded in a single task - in which case the
call to the function always needs to be func. In this case I was hoping to avoid
the double call with a (long) argument string by using some form of equivalence
or a function pointer.

NB the value of NOT_EMBEDDED is set in the call to the compiler (Norcroft)

NNB I apologise if my terminology is a bit shaky. In this case task means
a separate program.[/QUOTE]

It sounds as if you just want to change the name
of the function depending on whether it's "embedded"
or not (whatever that means). If so, won't

#if NOT_EMBEDDED
#define funca func
#endif

double funca(...) { ... }

do the trick?
 
M

Mr John FO Evans

Eric Sosman said:
Mr John FO Evans wrote On 03/25/06 18:18,:

I was attempting to allow a function to have effectively two entry points
(easy in assembler) so that it could be called from either. I also need to
disable one entry point or switch entry points using a compiler directive.

The current code (which is fine) is:-

double funca(<args>) /* args is always the same */
{
'''''
return <double>;
}

#if NOT_EMBEDDED
double func(<args>)
{
return funca(<args>);
}
#endif

If a number of code fragments as above are embedded in a single task that
task
can call funca (or funcb etc). The Linker requires that the unused entry point
func (which will be in every fragment) is disabled in this case.

Alternatively each function may be embedded in a single task - in which case the
call to the function always needs to be func. In this case I was hoping to
avoid
the double call with a (long) argument string by using some form of equivalence
or a function pointer.

NB the value of NOT_EMBEDDED is set in the call to the compiler (Norcroft)

NNB I apologise if my terminology is a bit shaky. In this case task means
a separate program.

It sounds as if you just want to change the name
of the function depending on whether it's "embedded"
or not (whatever that means). If so, won't

#if NOT_EMBEDDED
#define funca func
#endif

double funca(...) { ... }

do the trick?
[/QUOTE]
Yes of course - it works.

Thanks a lot

John

PS By embedded I simply meant included in the main program and not a
separate program exchanging data with the main.

In this application it is convenient to test the function in a separate
program before building it into the main program - even more convenient if
the function code can be identical in both environments.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top