473,395 Members | 1,437 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Should I do that...?

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?

#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;
}

Nov 15 '05 #1
17 1471
in**@bitart.at said:
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
Nov 15 '05 #2
in**@bitart.at wrote:
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?
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 (ir*******@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
Nov 15 '05 #3
On Wed, 14 Sep 2005 12:48:07 +0200, Irrwahn Grausewitz wrote:

....
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
Nov 15 '05 #4
Dear Richard,

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

Nov 15 '05 #5
Lawrence Kirby <lk****@netactive.co.uk> wrote:
On Wed, 14 Sep 2005 12:48:07 +0200, Irrwahn Grausewitz wrote:

<snip>
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.


</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 ...
--
Irrwahn Grausewitz (ir*******@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
Nov 15 '05 #6
in**@bitart.at wrote:
Hello World,

The code below compiles without warnings and the resulting program runs
without any error.
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.

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;
}

Nov 15 '05 #7

in**@bitart.at wrote:
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?

#include <stdio.h>

void Func1()
/*
** 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.
for ( i = 0; i < 3; i++ ) StartFunctions( v[i] );
return 0;
}


Nov 15 '05 #8
On 14 Sep 2005 04:45:27 -0700,
in**@bitart.at <in**@bitart.at> wrote:
Dear Richard,

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.

Depends on the compiler. Some compilers for 8 bit microcontrollers also
include an option to make int 8 bits.

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.

http://tjw.hn.org/ http://www.locofungus.btinternet.co.uk/
Nov 15 '05 #9
Tim Woodall <de*****@woodall.me.uk> writes:
On 14 Sep 2005 04:45:27 -0700,
in**@bitart.at <in**@bitart.at> wrote:
Dear Richard,

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.

Depends on the compiler. Some compilers for 8 bit microcontrollers also
include an option to make int 8 bits.


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.
Nov 15 '05 #10
Irrwahn Grausewitz wrote:
in**@bitart.at wrote:
int main()


This isn't one of the two legitimate declarations of main, use:

int main( void )


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.
Nov 15 '05 #11
Simon Biber wrote:
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.


Function definitions are also declarations.

--
pete
Nov 15 '05 #12
pete wrote:
Simon Biber wrote:
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.


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.

--
Simon.
Nov 15 '05 #13
In article <43***********************@news.optusnet.com.au> ,
Simon Biber <ne**@ralmin.cc> wrote:
pete wrote:
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!
Nov 15 '05 #14
> Of course there are dangers in writing broken code.
I'll gonna tell this my predecessor :)

Nov 15 '05 #15
in**@bitart.at wrote on 14/09/05 :
Hello World,

The code below compiles without warnings and the resulting program runs
without any error.
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.
Nov 15 '05 #16
Emmanuel Delahaye wrote:
in**@bitart.at wrote on 14/09/05 :
int main (void)
{
size_t i;
Tfun *v[] =
{
Func1,
Func2,
Func3,
};

for (i = 0; i < 3; i++)
{
StartFunctions (v[i]);
}
return 0;
}

I'm just curious about How can I traverse the array V with pointer,
I've tried something like
VFUNCV *p;
for (p = *v; *p; p++) StartFunctions(*p);

but that result core dump, Any hints to make it by poniter,
Thanks,
whatluo

Nov 15 '05 #17
Huajian Luo wrote:
I'm just curious about How can I traverse the array V with pointer,
I've tried something like
VFUNCV *p;
for (p = *v; *p; p++) StartFunctions(*p);

but that result core dump, Any hints to make it by poniter,


#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.
Nov 15 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: dr. zoidberg | last post by:
Hello, I'm trying to create login system. I need some advices. Should I put Username and Password in session, and then check database for correct combination on every page, or should I just put...
2
by: Stefan Behnel | last post by:
Hi! frozenset() doesn't behave as the other immutable empty data types in 2.4: ..>>> '' is '' True ..>>> () is () True ..>>> frozenset() is frozenset() False
40
by: Steve Juranich | last post by:
I know that this topic has the potential for blowing up in my face, but I can't help asking. I've been using Python since 1.5.1, so I'm not what you'd call a "n00b". I dutifully evangelize on the...
5
by: davidw | last post by:
Last time, I asked a question about if a XPathDocument could be serialized. Actually what I really want to know is how should I do in this case: I have a class that will be serialized. In the...
1
by: rajbala.3399 | last post by:
Hai all, I need to get multiple image buttonsand wheni click on the image button it should display corresponding image on window and if i click another image button it is also display on same...
5
by: Nirjhar Oberoi | last post by:
Hi, Question 1: I want your help on choosing what OS should one use to learn C Programming? I was thinking of installing Linux because a large no of tools are preconfigured in it.. I just...
3
by: assgar | last post by:
Hi I thought I had resolved this problem but I am intermittently the receving the warnings below. This code consist of a 1) HTML form, 2) a display function on the HTML form and 3) a...
10
by: Dancefire | last post by:
Hi, everyone, I'm writing a program using wstring(wchar_t) as internal string. The problem is raised when I convert the multibyte char set string with different encoding to wstring(which is...
0
by: hennas | last post by:
Basically i want to design a membership Name and Telephone List form using the following command buttons. Edit Add New; Update; Delete; Cancel; Save; Clear, and Exit
4
by: sinbad | last post by:
how can i write a program, which should accept input as NAME of a variable in the program and print it's value.Is this possible. for example. int main () { int x,y,z; x = 10; y = 20; z = 30;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.