Do Not Understand why these three Files Will Not Compile

K

KevinSimonson

I've created the three files below and have gotten them into Visual
Studio 2010 (version 10.0.30319.1). I had a whole bunch of
compilation errors, but I've got them all fixed but two in "Bug.cpp".
I've embedded the error messages into the code with square brackets to
make it easier to see what the messages are referring to. What I'm
trying to do is get an example of a non-static function being called
every ten seconds. All this program does is write the contents of a
"Bug" object to a different file each time "problem()" is called.
This isn't the real software problem I'm working on; the one I'm
working on is much more complex. But the part I'm having trouble with
with the real software problem is this bit where a call to
"SetTimer()" needs to call a non-static method. Anybody have any idea
why this code won't compile for me?

Kevin S

---
BugMain.cpp------------------------------------------------------------------
// BugMain.cpp : Defines the entry point for the console application.
//

#include "Bug.h"
#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
Bug bg = new Bug( 123, 456.789);
bg.runIt();
return 0;
}
---
Bug.h------------------------------------------------------------------------
#pragma once

class Bug
{
private:
int abc;
double def;

public:
Bug ( int ab, double de);

void runIt ();

void problem ();

static void* pObject;
};
---
Bug.cpp----------------------------------------------------------------------
#include "Bug.h"
#include <windows.h>
#include <stdio.h>
#include <fstream>
using namespace std;

char fileName[ 12];

Bug::Bug ( int ab
, double de)
{
abc = ab;
def = de;
strcpy( fileName, "Bug_000.Txt");
}

void CALLBACK repeatable ( HWND hwnt
, UINT uMsg
, UINT idEvent
, DWORD dwTime)
{
Bug* bg = (Bug *) pObject; [Error: identifier "pObject" is
undefined]
bg->problem();
}

void Bug::runIt ()
{
pObject = this;
SetTimer( NULL, 10000, repeatable); [Error: argument of type
"void (__stdc
} all *)(HWND hwnt, UINT uMsg,
UINT idEv
ent, DWORD dwTime)" is
incompatible wi
void Bug::problem () th parameter of type "UINT"]
{
ofstream outFile( fileName);
outFile << "abc == " << abc << " and def == " << def << "." << endl;
outFile.close();
int dgt;
for (dgt = 6; 3 < dgt && fileName[ dgt] == '9'; dgt--)
{ fileName[ dgt] = '0';
}
if (3 < dgt)
{ fileName[ dgt]++;
}
}
 
K

KevinSimonson

That last error message got kind of mangled. It refers to the line
where I call 'SetTimer( NULL, 10000, repeatable);' and should say,
'Error: argument of type "void (__stdcall *)(HWND hwnt, UINT uMsg,
UINT idEvent, DWORD dwTime)" is incompatible with parameter of type
"UINT"'.
 
S

Stuart Golodetz

I've created the three files below and have gotten them into Visual
Studio 2010 (version 10.0.30319.1). I had a whole bunch of
compilation errors, but I've got them all fixed but two in "Bug.cpp".
I've embedded the error messages into the code with square brackets to
make it easier to see what the messages are referring to. What I'm
trying to do is get an example of a non-static function being called
every ten seconds. All this program does is write the contents of a
"Bug" object to a different file each time "problem()" is called.
This isn't the real software problem I'm working on; the one I'm
working on is much more complex. But the part I'm having trouble with
with the real software problem is this bit where a call to
"SetTimer()" needs to call a non-static method. Anybody have any idea
why this code won't compile for me?

Kevin S

---
BugMain.cpp------------------------------------------------------------------
// BugMain.cpp : Defines the entry point for the console application.
//

#include "Bug.h"
#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
Bug bg = new Bug( 123, 456.789);
bg.runIt();
return 0;
}
---
Bug.h------------------------------------------------------------------------
#pragma once

class Bug
{
private:
int abc;
double def;

public:
Bug ( int ab, double de);

void runIt ();

void problem ();

static void* pObject;
};
---
Bug.cpp----------------------------------------------------------------------
#include "Bug.h"
#include<windows.h>
#include<stdio.h>
#include<fstream>
using namespace std;

char fileName[ 12];

Bug::Bug ( int ab
, double de)
{
abc = ab;
def = de;
strcpy( fileName, "Bug_000.Txt");
}

void CALLBACK repeatable ( HWND hwnt
, UINT uMsg
, UINT idEvent
, DWORD dwTime)
{
Bug* bg = (Bug *) pObject; [Error: identifier "pObject" is
undefined]
bg->problem();
}

void Bug::runIt ()
{
pObject = this;
SetTimer( NULL, 10000, repeatable); [Error: argument of type
"void (__stdc
} all *)(HWND hwnt, UINT uMsg,
UINT idEv
ent, DWORD dwTime)" is
incompatible wi
void Bug::problem () th parameter of type "UINT"]
{
ofstream outFile( fileName);
outFile<< "abc == "<< abc<< " and def == "<< def<< "."<< endl;
outFile.close();
int dgt;
for (dgt = 6; 3< dgt&& fileName[ dgt] == '9'; dgt--)
{ fileName[ dgt] = '0';
}
if (3< dgt)
{ fileName[ dgt]++;
}
}

Well you're off-topic in comp.lang.c++, but judging by this:

http://msdn.microsoft.com/en-us/library/ms644906(VS.85).aspx

It looks like you're passing three arguments to SetTimer when it expects
four. The result of that is that you're trying to pass uElapse (10000 in
your case) as nIDEvent, and lpTimerFunc (repeatable in your case) as
uElapse. Since repeatable is a callback function, not a UINT, you get
the error shown.

Suggested fix would be to pass in a suitable nIDEvent. Perhaps 0, since
you don't want to replace an existing timer, as in:

SetTimer(NULL, 0, 10000, repeatable);

Hope that fixes it -- it's a bit "off the top of my head", but in case
it helps.

---> And please don't post Windows-specific messages to comp.lang.c++
where they're not on-topic <---

Cheers,
Stu
 
U

Ulrich Eckhardt

KevinSimonson said:
int _tmain(int argc, _TCHAR* argv[])

For the record: This is a non-standard MSC-ism.
Bug bg = new Bug( 123, 456.789);
bg.runIt();

Please go back to your C++ and Java textbooks, and compare the syntax used
to instantiate objects. This here is Java syntax, but you are writing C++.
Generally, in C++ you don't use "new", unless you have a reason to.
#pragma once

Another non-portable construct, just for the record.
class Bug
{ [...]
static void* pObject;
};

The class (not instances thereof) contains a pointer-to-void named pObject.
char fileName[ 12];

void CALLBACK repeatable ( HWND hwnt
, UINT uMsg
, UINT idEvent
, DWORD dwTime)
{
Bug* bg = (Bug *) pObject; [Error: identifier "pObject" is
undefined]
bg->problem();
}

1. Don't use C-style casts. I guess that either a static cast or a
reinterpret_cast would be better here.
2. The compiler sees "pObject" and tries to look up that name. A bit
simplified, it first looks at local variables, then at the function
parameters and then at globals. There is no "pObject" in either of them,
the only "pObject" is inside class "Bug". If you mean that,
use "Bug::pObject".

Generally, but that is now specific to the use of the win32 API, you should
try to avoid passing parameters via "globals" like above. Instead, find out
which of the callback parameters you can use to pass context info to it.

Uli
 
G

Geoff

I've created the three files below and have gotten them into Visual
Studio 2010 (version 10.0.30319.1). I had a whole bunch of
compilation errors, but I've got them all fixed but two in "Bug.cpp".
I've embedded the error messages into the code with square brackets to
make it easier to see what the messages are referring to. What I'm
trying to do is get an example of a non-static function being called
every ten seconds. All this program does is write the contents of a
"Bug" object to a different file each time "problem()" is called.
This isn't the real software problem I'm working on; the one I'm
working on is much more complex. But the part I'm having trouble with
with the real software problem is this bit where a call to
"SetTimer()" needs to call a non-static method. Anybody have any idea
why this code won't compile for me?

Kevin S

---
BugMain.cpp------------------------------------------------------------------
// BugMain.cpp : Defines the entry point for the console application.
//

#include "Bug.h"

Bad practice. Don't include your headers before your project's master
header.
#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
Bug bg = new Bug( 123, 456.789);
bg.runIt();
return 0;
}
---
Bug.h------------------------------------------------------------------------
#pragma once

class Bug
{
private:
int abc;
double def;

public:
Bug ( int ab, double de);

void runIt ();

void problem ();

static void* pObject;
};
---
Bug.cpp----------------------------------------------------------------------
#include "Bug.h"
#include <windows.h>
#include <stdio.h> <--- delete this
#include <fstream>
#include said:
using namespace std;

char fileName[ 12];

Are you writing C or C++? Forget char exists.

string fileName;
Bug::Bug ( int ab
, double de)
{
abc = ab;
def = de;
strcpy( fileName, "Bug_000.Txt"); <-- no!

Are you writing C?

fileName = "Bug_000.Txt";
void CALLBACK repeatable ( HWND hwnt
, UINT uMsg
, UINT idEvent
, DWORD dwTime)
{
Bug* bg = (Bug *) pObject; [Error: identifier "pObject" is
undefined]
bg->problem();
}

Now you are writing C to the Windows API but trying to instantiate an
object directly.
void Bug::runIt ()
{
pObject = this;
SetTimer( NULL, 10000, repeatable); [Error: argument of type

Invalid number of arguments to the function.
"void (__stdc
} all *)(HWND hwnt, UINT uMsg,
UINT idEv
ent, DWORD dwTime)" is
incompatible wi
void Bug::problem () th parameter of type "UINT"]
{
ofstream outFile( fileName);
outFile << "abc == " << abc << " and def == " << def << "." << endl;
outFile.close();
int dgt;
for (dgt = 6; 3 < dgt && fileName[ dgt] == '9'; dgt--)
{ fileName[ dgt] = '0';
}
if (3 < dgt)
{ fileName[ dgt]++;
}
}

You are trying to use Windows messages, (WM_TIMER) in a console
application without a WindowProc and without a message loop. A console
application doesn't receive these kinds of messages and your timer
callback will never be called.
 
P

Paul N

Other people have pointed out various things, but Ithink I have
spotted a couple of extra problems:

Anybody have any idea
why this code won't compile for me?
BugMain.cpp----------------------------------------------------------------­--
// BugMain.cpp : Defines the entry point for the console application.
//

#include "Bug.h"
#include "stdafx.h"

I'm not an expert, but I think that VC++ will actually ignore anything
before #include "stdafx.h" and so the stuff in Bug.h won't actually
get included.
---
Bug.h----------------------------------------------------------------------­--
#pragma once

class Bug
{
private:
     int abc;
  double def;

public:
  Bug ( int ab, double de);

  void runIt ();

  void problem ();

  static void* pObject;};

(note that pObject is therefore a member variable of this class)

void CALLBACK repeatable (  HWND hwnt
                         ,  UINT uMsg
                         ,  UINT idEvent
                         , DWORD dwTime)
{
  Bug* bg = (Bug *) pObject;          [Error: identifier "pObject" is
undefined]

Here you are not in a member function, so there is no variable
pObject. (And, yes, this is the sort of problem that *is* on-topic in
comp.lang.c++.)

Hope this helps.
Paul.
 
S

Stuart Golodetz

Other people have pointed out various things, but Ithink I have
spotted a couple of extra problems:

Anybody have any idea
why this code won't compile for me?
BugMain.cpp----------------------------------------------------------------­--
// BugMain.cpp : Defines the entry point for the console application.
//

#include "Bug.h"
#include "stdafx.h"

I'm not an expert, but I think that VC++ will actually ignore anything
before #include "stdafx.h" and so the stuff in Bug.h won't actually
get included.
---
Bug.h----------------------------------------------------------------------­--
#pragma once

class Bug
{
private:
int abc;
double def;

public:
Bug ( int ab, double de);

void runIt ();

void problem ();

static void* pObject;};

(note that pObject is therefore a member variable of this class)

void CALLBACK repeatable ( HWND hwnt
, UINT uMsg
, UINT idEvent
, DWORD dwTime)
{
Bug* bg = (Bug *) pObject; [Error: identifier "pObject" is
undefined]

Here you are not in a member function, so there is no variable
pObject. (And, yes, this is the sort of problem that *is* on-topic in
comp.lang.c++.)

Hope this helps.
Paul.

Aye, that one's definitely on-topic :) I think I scrolled down too fast
and only saw the second problem.

Cheers,
Stu
 
J

Jorgen Grahn

["Followup-To:" header set to comp.lang.c++.]

Bad practice. Don't include your headers before your project's master
header.

Why would that be a bad practice? I (and others) believe it's a good
practice, because it ensures that "Bug.h" includes everything it
needs, so you don't get cascading build failures as you remove an
#include somewhere else.

(I don't know what a "project's master header" is, but I assume things
like <iostream> and <vector> fit the description.)

/Jorgen
 
C

Charlie Gibbs

["Followup-To:" header set to comp.lang.c++.]

Bad practice. Don't include your headers before your project's master
header.

Why would that be a bad practice? I (and others) believe it's a good
practice, because it ensures that "Bug.h" includes everything it
needs, so you don't get cascading build failures as you remove an
#include somewhere else.

My procedure would be to move the #include "stdafx.h" (and
any other system includes) inside Bug.h - which will then
include _everything_ it needs.
 
J

Jorgen Grahn

["Followup-To:" header set to comp.lang.c++.]

On Thu, 4 Nov 2010 16:23:16 -0700 (PDT), KevinSimonson ...
BugMain.cpp---------------------------------------------------------
// BugMain.cpp : Defines the entry point for the console application.
/ /

#include "Bug.h"

Bad practice. Don't include your headers before your project's master
header.

#include "stdafx.h"

Why would that be a bad practice?

[Someone elsewhere explained that was a Microsoft-specific advice,
having to do with their precompiled headers or something.]
My procedure would be to move the #include "stdafx.h" (and
any other system includes) inside Bug.h - which will then
include _everything_ it needs.

But that would make Bug.h include everything BugMain.cpp needs, which
is probably a whole lot more than Bug.h itself needs. A lot of people
(me, for example) aren't willing to pay the price for that.

/Jorgen
 

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

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top