Connecting Tech Pros Worldwide Forums | Help | Site Map

C++ rookie having trouble. Anybody care to try to help?

Don Bruder
Guest
 
Posts: n/a
#1: Jul 19 '05
Got a stumper here. I imagine that for someone experienced in C++, this
is too pathetic for words. For a rookie, using this project as a sort
of "midterm exam" in his self-taught "how to program in C++" course,
it's seeming to be an insurmountable problem. Can anyone assist? I'm at
wit's end here. Everything *LOOKS* (to this rookie, anyway) correct,
but the compiler is barfing on it.

Here's the class declaration for Bar
class Bar
{
private:
int Done;
char File[254];
float PartDone;
int Time;
char SaveTo[254];
int DRate;
int URate;
int Action;

public:
Bar();
~Bar();
void Finished(void);
void Failed(void);
void Error(char *ErrorMsg);
void Display(float PercentDone, int Time, int DRate,
int URate, int Action);
void ChooseFile(char *DefaultName, int MaxFileNameSize,
char *SaveTo, char *Dir);
void NewPath(char *Path);
void DoIt(char **argv);
};

Here's the header file that declares routine Foo:

int Foo(char **args,
void (*FileFunc)(char *, int, char *, char *),
void (*StatusFunc)(float, int, int, int, int),
void (*FinishFunc)(void),
void (*ErrorFunc)(char *),
int *DoneFlag,
int Cols,
void (*PathFunc)(char *)
);

And finally, here's where/how Foo gets called:

void Bar::DoIt(char **argv)

{
Foo(argv,
(void (*)(char *, int, char *, char *)) this->ChooseFile, <--- 1
(void (*)(float, int, int, int, int)) this->Display, <--- 2
(void (*)(void)) this->Finished, <--- 3
(void (*)(char *)) this->Error, <--- 4
&this->Done,
80,
(void (*)(char *)) this->NewPath <--- 5
);
if (!this->Done)
this->Failed();
}

int main(int argc, char **argv)

{
// I just plain don't care about argc, so shut up about it, compiler!
#pragma unused (argc)

Bar FooBar;

FooBar.DoIt(argv);
}

Lines marked on the right margin with "<--- #" indicate where the
compiler barfs at me. The specific errors reported for each "#" are:

1:
Error : illegal explicit conversion from 'void' to 'void (*)(char *,
int, char *, char *)'
Baz.c++ line 268 (void (*)(char *, int, char *, char *))
this->ChooseFile,

2:
Error : illegal explicit conversion from 'void' to 'void (*)(float,
int, int, int, int)'
Baz.c++ line 269 (void (*)(float, int, int, int, int)) this->Display,

3:
Error : illegal explicit conversion from 'void' to 'void (*)()'
BTDownloadHeadless.c++ line 270 (void (*)(void)) this->Finished,

4:
Error : illegal explicit conversion from 'void' to 'void (*)(char *)'
Baz.c++ line 271 (void (*)(char *)) this->Error,

5:
Error : illegal explicit conversion from 'void' to 'void (*)(char *)'
Baz.c++ line 274 (void (*)(char *)) this->NewPath

As can be seen, they're basicaly the same error in all cases, with
variations for the exact cast that's happening.

So what, precisely, am I doing wrong??? Everything I can find in either
K&R C, 2nd, or Stroustrup C++ 3rd shows me that this *SHOULD BE*
perfectly legal code (although I freely grant that it may be *CRAPPY*
code, style-wise... That's a whole different topic...) yet for some
reason, I'm getting compiler barfs that are stopping me in my tracks.
The 5 errors listed are the only ones anywhere in the code (at least as
far as the compiler reports to this point) - everything else except the
file containing main() and DoIt() compiles without complaint.

Anybody got some advice for me? What is it I'm doing wrong, and how/why
is it wrong?

--
Don Bruder - dakidd@sonic.net <--- Preferred Email - SpamAssassinated.
Hate SPAM? See <http://www.spamassassin.org> for some seriously great info.
I will choose a path that's clear: I will choose Free Will! - N. Peart
Fly trap info pages: <http://www.sonic.net/~dakidd/Horses/FlyTrap/index.html>

White Wolf
Guest
 
Posts: n/a
#2: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?


Don Bruder wrote:
[SNIP][color=blue]
> (void (*)(char *, int, char *, char *)) this->ChooseFile,[/color]

As far as I understand you need to take the address of that function. But
you cannot. It is a call to a member function. It has no address
convertable to a "normal" C-style function pointer due to the
[color=blue]
> So what, precisely, am I doing wrong??? Everything I can find in
> either K&R C,[/color]

K&R C has no classes and member functions, so I doubt that it contains
anything like the above.
[color=blue]
> 2nd, or Stroustrup C++ 3rd shows me that this *SHOULD
> BE* perfectly legal code[/color]

I also very much doubt that Stroustrup would say that you can convert a
member function (pointer) into a normal C-style function pointer.

Please, if you really wish to learn about this function pointer things read
this excellent article from Herb Sutter:

http://www.cuj.com/documents/s=8464/cujcexp0308sutter/

It is describing a candidate for a new standard library element, one which
can be used to pass around any functions, be it member or not. The existing
implementation of it you can find at

http://www.boost.org

--
WW aka Attila


Mike Wahler
Guest
 
Posts: n/a
#3: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?



"Don Bruder" <dakidd@sonic.net> wrote in message
news:0Ypab.22630$dk4.705624@typhoon.sonic.net...[color=blue]
> Got a stumper here. I imagine that for someone experienced in C++, this
> is too pathetic for words. For a rookie, using this project as a sort
> of "midterm exam" in his self-taught "how to program in C++" course,
> it's seeming to be an insurmountable problem. Can anyone assist? I'm at
> wit's end here. Everything *LOOKS* (to this rookie, anyway) correct,
> but the compiler is barfing on it.
>
> Here's the class declaration for Bar
> class Bar
> {
> private:
> int Done;
> char File[254];
> float PartDone;
> int Time;
> char SaveTo[254];
> int DRate;
> int URate;
> int Action;
>
> public:
> Bar();
> ~Bar();
> void Finished(void);
> void Failed(void);
> void Error(char *ErrorMsg);
> void Display(float PercentDone, int Time, int DRate,
> int URate, int Action);
> void ChooseFile(char *DefaultName, int MaxFileNameSize,
> char *SaveTo, char *Dir);
> void NewPath(char *Path);
> void DoIt(char **argv);
> };
>
> Here's the header file that declares routine Foo:
>
> int Foo(char **args,
> void (*FileFunc)(char *, int, char *, char *),
> void (*StatusFunc)(float, int, int, int, int),
> void (*FinishFunc)(void),
> void (*ErrorFunc)(char *),
> int *DoneFlag,
> int Cols,
> void (*PathFunc)(char *)
> );
>
> And finally, here's where/how Foo gets called:
>
> void Bar::DoIt(char **argv)
>
> {
> Foo(argv,
> (void (*)(char *, int, char *, char *)) this->ChooseFile, <--- 1
> (void (*)(float, int, int, int, int)) this->Display, <--- 2
> (void (*)(void)) this->Finished, <--- 3
> (void (*)(char *)) this->Error, <--- 4
> &this->Done,
> 80,
> (void (*)(char *)) this->NewPath <--- 5
> );
> if (!this->Done)
> this->Failed();
> }
>
> int main(int argc, char **argv)
>
> {
> // I just plain don't care about argc, so shut up about it, compiler!
> #pragma unused (argc)
>
> Bar FooBar;
>
> FooBar.DoIt(argv);
> }
>
> Lines marked on the right margin with "<--- #" indicate where the
> compiler barfs at me. The specific errors reported for each "#" are:
>
> 1:
> Error : illegal explicit conversion from 'void' to 'void (*)(char *,
> int, char *, char *)'
> Baz.c++ line 268 (void (*)(char *, int, char *, char *))
> this->ChooseFile,
>
> 2:
> Error : illegal explicit conversion from 'void' to 'void (*)(float,
> int, int, int, int)'
> Baz.c++ line 269 (void (*)(float, int, int, int, int)) this->Display,
>
> 3:
> Error : illegal explicit conversion from 'void' to 'void (*)()'
> BTDownloadHeadless.c++ line 270 (void (*)(void)) this->Finished,
>
> 4:
> Error : illegal explicit conversion from 'void' to 'void (*)(char *)'
> Baz.c++ line 271 (void (*)(char *)) this->Error,
>
> 5:
> Error : illegal explicit conversion from 'void' to 'void (*)(char *)'
> Baz.c++ line 274 (void (*)(char *)) this->NewPath
>
> As can be seen, they're basicaly the same error in all cases, with
> variations for the exact cast that's happening.
>
> So what, precisely, am I doing wrong??? Everything I can find in either
> K&R C, 2nd, or Stroustrup C++ 3rd shows me that this *SHOULD BE*
> perfectly legal code (although I freely grant that it may be *CRAPPY*
> code, style-wise... That's a whole different topic...) yet for some
> reason, I'm getting compiler barfs that are stopping me in my tracks.
> The 5 errors listed are the only ones anywhere in the code (at least as
> far as the compiler reports to this point) - everything else except the
> file containing main() and DoIt() compiles without complaint.
>
> Anybody got some advice for me? What is it I'm doing wrong, and how/why
> is it wrong?[/color]

The lines giving the errors look quite suspicious to me.
AFAIK, a pointer to a member function and a pointer to
a nonmember function are not 'compatible', and there's
no defined way to convert from one to the other.

What on Earth are you trying to do?

Have you tried using overloaded or virtual functions
to do the 'dispatching' it looks like you're trying to do?

-Mike


Alexei Betin
Guest
 
Posts: n/a
#4: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?


Your problem is that member functions have an implicit argument
- the "this" pointer, and therefore their "true" signature - and type
depends on the class they are in.

In other words, functions

int f1( int a );
int A::f2( int a );
int B::f3( int a );

have, in fact quite different signatures and cannot be used interchangeably,
namely only the 1st one has a type of int (*) (int), while the second one
has a type of int (A::*) (int) etc.

Hope, this helps
~Alexei

"Don Bruder" <dakidd@sonic.net> wrote in message
news:0Ypab.22630$dk4.705624@typhoon.sonic.net...[color=blue]
> Got a stumper here. I imagine that for someone experienced in C++, this
> is too pathetic for words. For a rookie, using this project as a sort
> of "midterm exam" in his self-taught "how to program in C++" course,
> it's seeming to be an insurmountable problem. Can anyone assist? I'm at
> wit's end here. Everything *LOOKS* (to this rookie, anyway) correct,
> but the compiler is barfing on it.
>
> Here's the class declaration for Bar
> class Bar
> {
> private:
> int Done;
> char File[254];
> float PartDone;
> int Time;
> char SaveTo[254];
> int DRate;
> int URate;
> int Action;
>
> public:
> Bar();
> ~Bar();
> void Finished(void);
> void Failed(void);
> void Error(char *ErrorMsg);
> void Display(float PercentDone, int Time, int DRate,
> int URate, int Action);
> void ChooseFile(char *DefaultName, int MaxFileNameSize,
> char *SaveTo, char *Dir);
> void NewPath(char *Path);
> void DoIt(char **argv);
> };
>
> Here's the header file that declares routine Foo:
>
> int Foo(char **args,
> void (*FileFunc)(char *, int, char *, char *),
> void (*StatusFunc)(float, int, int, int, int),
> void (*FinishFunc)(void),
> void (*ErrorFunc)(char *),
> int *DoneFlag,
> int Cols,
> void (*PathFunc)(char *)
> );
>
> And finally, here's where/how Foo gets called:
>
> void Bar::DoIt(char **argv)
>
> {
> Foo(argv,
> (void (*)(char *, int, char *, char *)) this->ChooseFile, <--- 1
> (void (*)(float, int, int, int, int)) this->Display, <--- 2
> (void (*)(void)) this->Finished, <--- 3
> (void (*)(char *)) this->Error, <--- 4
> &this->Done,
> 80,
> (void (*)(char *)) this->NewPath <--- 5
> );
> if (!this->Done)
> this->Failed();
> }
>
> int main(int argc, char **argv)
>
> {
> // I just plain don't care about argc, so shut up about it, compiler!
> #pragma unused (argc)
>
> Bar FooBar;
>
> FooBar.DoIt(argv);
> }
>
> Lines marked on the right margin with "<--- #" indicate where the
> compiler barfs at me. The specific errors reported for each "#" are:
>
> 1:
> Error : illegal explicit conversion from 'void' to 'void (*)(char *,
> int, char *, char *)'
> Baz.c++ line 268 (void (*)(char *, int, char *, char *))
> this->ChooseFile,
>
> 2:
> Error : illegal explicit conversion from 'void' to 'void (*)(float,
> int, int, int, int)'
> Baz.c++ line 269 (void (*)(float, int, int, int, int)) this->Display,
>
> 3:
> Error : illegal explicit conversion from 'void' to 'void (*)()'
> BTDownloadHeadless.c++ line 270 (void (*)(void)) this->Finished,
>
> 4:
> Error : illegal explicit conversion from 'void' to 'void (*)(char *)'
> Baz.c++ line 271 (void (*)(char *)) this->Error,
>
> 5:
> Error : illegal explicit conversion from 'void' to 'void (*)(char *)'
> Baz.c++ line 274 (void (*)(char *)) this->NewPath
>
> As can be seen, they're basicaly the same error in all cases, with
> variations for the exact cast that's happening.
>
> So what, precisely, am I doing wrong??? Everything I can find in either
> K&R C, 2nd, or Stroustrup C++ 3rd shows me that this *SHOULD BE*
> perfectly legal code (although I freely grant that it may be *CRAPPY*
> code, style-wise... That's a whole different topic...) yet for some
> reason, I'm getting compiler barfs that are stopping me in my tracks.
> The 5 errors listed are the only ones anywhere in the code (at least as
> far as the compiler reports to this point) - everything else except the
> file containing main() and DoIt() compiles without complaint.
>
> Anybody got some advice for me? What is it I'm doing wrong, and how/why
> is it wrong?
>
> --
> Don Bruder - dakidd@sonic.net <--- Preferred Email - SpamAssassinated.
> Hate SPAM? See <http://www.spamassassin.org> for some seriously great[/color]
info.[color=blue]
> I will choose a path that's clear: I will choose Free Will! - N. Peart
> Fly trap info pages:[/color]
<http://www.sonic.net/~dakidd/Horses/FlyTrap/index.html>


Kevin Goodsell
Guest
 
Posts: n/a
#5: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?


Alexei Betin wrote:
[color=blue]
> Your problem is that...[/color]
<snip>

Please don't top. Read section 5 of the FAQ for posting guidelines. In
particular, read this:

http://www.parashift.com/c++-faq-lit...t.html#faq-5.4

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Alexei Betin
Guest
 
Posts: n/a
#6: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?



"Kevin Goodsell" <usenet1.spamfree.fusion@neverbox.com> wrote in message
news:huqab.8647$BS5.2835@newsread4.news.pas.earthl ink.net...[color=blue]
> Alexei Betin wrote:
>[color=green]
> > Your problem is that...[/color]
> <snip>
>
> Please don't top. Read section 5 of the FAQ for posting guidelines. In
> particular, read this:
>[/color]

got you, sorry, haven't been here a while...
[color=blue]
> http://www.parashift.com/c++-faq-lit...t.html#faq-5.4
>
> -Kevin
> --
> My email address is valid, but changes periodically.
> To contact me please use the address from a recent posting.
>[/color]


Christopher Benson-Manica
Guest
 
Posts: n/a
#7: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?


Alexei Betin <abetin@futuretrade.com> spoke thus:
[color=blue]
> Your problem is that member functions have an implicit argument
> - the "this" pointer, and therefore their "true" signature - and type
> depends on the class they are in.[/color]
[color=blue]
> In other words, functions[/color]
[color=blue]
> int f1( int a );
> int A::f2( int a );
> int B::f3( int a );[/color]
[color=blue]
> have, in fact quite different signatures and cannot be used interchangeably,
> namely only the 1st one has a type of int (*) (int), while the second one
> has a type of int (A::*) (int) etc.[/color]

Can this be mitigated somewhat by adding _closure to the prototypes...?

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Kevin Goodsell
Guest
 
Posts: n/a
#8: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?


Christopher Benson-Manica wrote:[color=blue]
>
> Can this be mitigated somewhat by adding _closure to the prototypes...?[/color]

"_closure"? What is that (other than a name reserved for the
implementation's use in the global namespace)?

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Mike Wahler
Guest
 
Posts: n/a
#9: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?



"Christopher Benson-Manica" <ataru@nospam.cyberspace.org> wrote in message
news:bkfo08$mgl$6@chessie.cirr.com...[color=blue]
> Alexei Betin <abetin@futuretrade.com> spoke thus:
>[color=green]
> > Your problem is that member functions have an implicit argument
> > - the "this" pointer, and therefore their "true" signature - and type
> > depends on the class they are in.[/color]
>[color=green]
> > In other words, functions[/color]
>[color=green]
> > int f1( int a );
> > int A::f2( int a );
> > int B::f3( int a );[/color]
>[color=green]
> > have, in fact quite different signatures and cannot be used[/color][/color]
interchangeably,[color=blue][color=green]
> > namely only the 1st one has a type of int (*) (int), while the second[/color][/color]
one[color=blue][color=green]
> > has a type of int (A::*) (int) etc.[/color]
>
> Can this be mitigated somewhat by adding _closure to the prototypes...?[/color]

There's no such keyword in C++. Is that some language
extension provided by your implementation?

See http://www.parashift.com/c++-faq-lit...o-members.html

-Mike


Alexei Betin
Guest
 
Posts: n/a
#10: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?


"Christopher Benson-Manica" <ataru@nospam.cyberspace.org> wrote in message
news:bkfo08$mgl$6@chessie.cirr.com...[color=blue]
> Alexei Betin <abetin@futuretrade.com> spoke thus:
>[/color]
<SNIP>[color=blue][color=green]
> > In other words, functions[/color]
>[color=green]
> > int f1( int a );
> > int A::f2( int a );
> > int B::f3( int a );[/color]
>[color=green]
> > have, in fact quite different signatures and cannot be used[/color][/color]
interchangeably,[color=blue][color=green]
> > namely only the 1st one has a type of int (*) (int), while the second[/color][/color]
one[color=blue][color=green]
> > has a type of int (A::*) (int) etc.[/color]
>
> Can this be mitigated somewhat by adding _closure to the prototypes...?
>[/color]

Not sure what _closure is.
If in fact you don't need the object instance - then use a static function
and you'll be fine, namely

static int A::f4( int )
has the same type as
int f1( int a );
and either can be passed to a function expecting int (*) (int)

But if it does need the object as a hidden argument to work on then how
can you possibly "mitigate" that?

You can do a forceful cast but the consequences will be disasterous
when it tries to access memory where it thinks "this" argument should be
found
(and maybe even before that due to a different memory layout for arguments
passing) - that is why the compiler will not allow that without
reinterpret_cast
or C-style cast.

~Alexei
[color=blue]
> --
> Christopher Benson-Manica | Jumonji giri, for honour.
> ataru(at)cyberspace.org |[/color]


Christopher Benson-Manica
Guest
 
Posts: n/a
#11: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?


Mike Wahler <mkwahler@mkwahler.net> spoke thus:
[color=blue]
> There's no such keyword in C++. Is that some language
> extension provided by your implementation?[/color]

Apparently yes. Sorry to bring it up. (one of I'm sure many reasons for
newbs like me to dislike starting with a complex environment like Borland C++
Builder, with lots of code written by other people to boot - can't tell what's
"standard" and what's implementation-defined...)

--
Christopher Benson-Manica | Jumonji giri, for honour.
ataru(at)cyberspace.org |
Kevin Goodsell
Guest
 
Posts: n/a
#12: Jul 19 '05

re: C++ rookie having trouble. Anybody care to try to help?


Christopher Benson-Manica wrote:
[color=blue]
> Mike Wahler <mkwahler@mkwahler.net> spoke thus:
>
>[color=green]
>>There's no such keyword in C++. Is that some language
>>extension provided by your implementation?[/color]
>
>
> Apparently yes. Sorry to bring it up. (one of I'm sure many reasons for
> newbs like me to dislike starting with a complex environment like Borland C++
> Builder, with lots of code written by other people to boot - can't tell what's
> "standard" and what's implementation-defined...)[/color]

Technically "implementation-defined" has a specific meaning that doesn't
apply here. Just thought I'd clarify to avoid future confusion. When the
standard describes something as "implementation-defined" it means that
an implementation is required to prescribe a particular behavior and
document that behavior. It may differ from one implementation to the
next, but must be consistent and as documented.

What you are referring to is a language extension.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Closed Thread