The code below compiles without warnings and the resulting program runs
without any error.
...somehow I am not sure if I should do something like this and/or if
there are any dangers...
Any comments?
#include <stdio.h>
void Func1()
{
printf("func1\n");
return;
}
void Func2()
{
printf("func2\n");
return;
}
void Func3()
{
printf("func3\n");
return;
}
void StartFunctions( void (*f)(void) )
{
printf("Starting Function...\n");
f();
return;
}
int main()
{
char i;
void *v[] = { (void*)Func1, (void*)Func2, (void*)Func3 };
for ( i = 0; i < 3; i++ ) StartFunctions( v[i] );
return 0;
}
> Hello World,
>
> The code below compiles without warnings and the resulting program runs
> without any error.
>
> ...somehow I am not sure if I should do something like this and/or if
> there are any dangers...
>
> Any comments?
Although it is a common extension, the conversion between function pointers
and void pointers is not guaranteed by the Standard to be lossless. I have
corrected that problem in your code, below. I have also introduced a
typedef, since it makes the whole thing easier to read, and added a couple
of comments which I recommend that you read.
#include <stdio.h>
typedef void VFUNCV(void);
void Func1(void)
{
printf("func1\n");
return;
}
void Func2(void)
{
printf("func2\n");
return;
}
void Func3(void)
{
printf("func3\n");
return;
}
void StartFunctions( VFUNCV *f )
{
printf("Starting Function...\n");
f(); /* I would prefer (*f)(); on the grounds that it reminds
* us a function pointer is being used here. Either works.
*/
return;
}
int main()
{
char i; /* Why char? What are you trying to save, and why? */
VFUNCV *v[] = { Func1, Func2, Func3 };
for ( i = 0; i < 3; i++ ) StartFunctions( v[i] );
return 0;
}
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/2005
http://www.cpax.org.uk
email: rjh at above domain
See below.
>#include <stdio.h>
>
>void Func1()
Change this to:
void Func1( void )
to match the pointer declarations below.
>{
> printf("func1\n");
> return;
>}
>
>void Func2()
Same here.
>{
> printf("func2\n");
> return;
>}
>
>void Func3()
Same here.
>{
> printf("func3\n");
> return;
>}
>
>void StartFunctions( void (*f)(void) )
>{
> printf("Starting Function...\n");
> f();
> return;
>}
>
>int main()
This isn't one of the two legitimate declarations of main, use:
int main( void )
>{
> char i;
Using a character value for array subscripting is at least suspicious;
no, wait, it's actually a constraint violation. Use:
int i;
> void *v[] = { (void*)Func1, (void*)Func2, (void*)Func3 };
In order to avoid pointer type mismatches you presumably want:
void (*v[])(void) = { Func1, Func2, Func3 };
Note: cluttering your code with spurious casts is the wrong approach.
Better use correct declarations in the first place.
> for ( i = 0; i < 3; i++ ) StartFunctions( v[i] );
Minor quibble: beware of magic numbers (3).
> return 0;
That's fine. :o)
>}
HTH
Best regards.
--
Irrwahn Grausewitz (irrw...@freenet.de)
welcome to clc : http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc frequent answers: http://benpfaff.org/writings/clc
...
> int main( void )
>
>>{
>> char i;
>
> Using a character value for array subscripting is at least suspicious;
> no, wait, it's actually a constraint violation. Use:
>
> int i;
That is better, however you can use any integer type for an array
subscript (or more specifically pointer arithemtic) and character types
are perfectly good integer types.
>> void *v[] = { (void*)Func1, (void*)Func2, (void*)Func3 };
>
> In order to avoid pointer type mismatches you presumably want:
>
> void (*v[])(void) = { Func1, Func2, Func3 };
>
> Note: cluttering your code with spurious casts is the wrong approach.
> Better use correct declarations in the first place.
>
>> for ( i = 0; i < 3; i++ ) StartFunctions( v[i] );
This would also have been an error in the original code, you cannot
convert from void * to a funciton pointer type without a cast.
Lawrence
thank you for your corrections
char i; /* Why char? What are you trying to save, and why? */
That was one of my questions. I wonder if I save _any_ memory by using
char instead of int.
The target of my application is a microcontroller where I really need
to save memory. The application will be compiled with 1 byte alignment.
yours,
Herwig
</me slaps forehead> Argh, I did it again. Note to self:
I shall not read the standard hastily.
I shall not read the standard hastily.
I shall not ...
Then either you have an unhelpful compiler or you have your diagnostics
incorrectly set. I get, for example
a.c: In function 'main':
a.c:42: warning: ISO C forbids conversion of function pointer to object
pointer type
a.c:42: warning: ISO C forbids conversion of function pointer to object
pointer type
a.c:42: warning: ISO C forbids conversion of function pointer to object
pointer type
a.c:44: warning: array subscript has type 'char'
a.c:44: warning: ISO C forbids passing argument 1 of 'StartFunctions'
between function pointer and 'void *'
To fix this is easy. Change
> void *v[] = { (void*)Func1, (void*)Func2, (void*)Func3 };
to
void (*v[])() = { Func1, Func2, Func3 };
> ...somehow I am not sure if I should do something like this and/or if
> there are any dangers...
Of course there are dangers in writing broken code.
/*
** make sure function prototypes match
** the prototype in StartFunctions
*/
void Func1(void)
> {
> printf("func1\n");
> return;
> }
>
> void Func2()
void Func2(void)
> {
> printf("func2\n");
> return;
> }
>
> void Func3()
void Func3(void)
> {
> printf("func3\n");
> return;
> }
>
> void StartFunctions( void (*f)(void) )
> {
> printf("Starting Function...\n");
> f();
> return;
> }
>
> int main()
> {
> char i;
> void *v[] = { (void*)Func1, (void*)Func2, (void*)Func3 };
void (*v[])(void) = {Func1, Func2, Func3};
Converting between object and function pointers is bad juju.
You may also find that this is one place where register might make a
difference.
Tim.
--
God said, "div D = rho, div B = 0, curl E = - @B/@t, curl H = J + @D/@t,"
and there was light.
This is, of course, non-conforming; int is required to be able to hold
values in the range -32767 .. +32767. (But "non-conforming" is not
synonymous with "evil"; there's nothing wrong with creating an
implementation for something that's not quite C, as long as you don't
claim that it conforms to the C standard.)
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
The standard requires main to be defined with a type equivalent to one
of the two legitimate declarations. The OP's definition is equivalent,
and so perfectly valid.
To make it clear: leaving out the "void" in the parameter list of a
function _definition_ makes no difference. Leaving it out in a
_declaration_ does make a difference.
--
Simon.
Function definitions are also declarations.
--
pete
True, but this only matters if you're going to call the function from a
subsequent function.
As I was talking about the definition of the main function, this is
something which, hopefully, no-one does in practice.
--
Simon.
>> Function definitions are also declarations.
>True, but this only matters if you're going to call the function from a
>subsequent function.
>As I was talking about the definition of the main function, this is
>something which, hopefully, no-one does in practice.
clc often has examples of people calling main recursively
(at, at the very least, cursedly.)
I wouldn't expect calling recursing to main to be -common-, but
it apparently does happen in real life.
--
This signature intentionally left... Oh, darn!
Get a better compiler or learn how to tune it..
main.c:8: warning: function declaration isn't a prototype
main.c:14: warning: function declaration isn't a prototype
main.c:20: warning: function declaration isn't a prototype
main.c:26: warning: no previous prototype for 'StartFunctions'
main.c: In function `main_':
main.c:36: warning: array subscript has type `char'
> ...somehow I am not sure if I should do something like this and/or if
> there are any dangers...
#include <stdio.h>
typedef void Tfun (void);
static void Func1 (void)
{
printf ("func1\n");
return;
}
static void Func2 (void)
{
printf ("func2\n");
return;
}
static void Func3 (void)
{
printf ("func3\n");
return;
}
static void StartFunctions (void (*f) (void))
{
printf ("Starting Function...\n");
f ();
return;
}
int main (void)
{
size_t i;
Tfun *v[] =
{
Func1,
Func2,
Func3,
};
for (i = 0; i < 3; i++)
{
StartFunctions (v[i]);
}
return 0;
}
--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html
"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.
but that result core dump, Any hints to make it by poniter,
Thanks,
whatluo
#include <stdio.h>
typedef void VFUNCV(void);
void func1(void)
{
printf("func1\n");
}
void func2(void)
{
printf("func2\n");
}
void func3(void)
{
printf("func3\n");
}
VFUNCV *array[] =
{
func1,
func2,
func3
};
int main(void)
{
VFUNCV **p;
VFUNCV **end = array + sizeof array / sizeof *array;
for(p = array; p != end; ++p)
{
(*p)();
}
return 0;
}
--
Simon.