Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help with Compile Error :)

1 view
Skip to first unread message

Kush

unread,
Jul 19, 2008, 4:42:04 PM7/19/08
to
Hello,

I am attempting to create a small program to teach a colleague how to
program using C++ but I seem to be having my own difficulties with a
compile error. It has been quite some time since I last wrote code in
general, led alone in C++.

I was wondering if someone wouldn't mind pointing out the source of my
problem. :)

The compile error I am getting is below and occurs in the
RunProgram :: Run method definition

error C2228: left of '.GetRunnersNameByIndex' must have class/struct/
union type
error C2228: left of '.GetRaceTimePerRunnerByIndex' must have class/
struct/union type
error C2228: left of '.GetEnvironmentalCoefficient' must have class/
struct/union type

A code snippet is pasted below:

Any help is appreciated! :)

Cheers,

Kush

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
class EnvironmentalFactors
{
private:
Terrain CurrentTerrain;
WeatherConditions CurrentWeather;

double EnvironmentalCoefficient;
void CalculateEnvironmentalCoefficient (void);

public:
EnvironmentalFactors();
double GetEnvironmentalCoefficient (void);
};

EnvironmentalFactors :: EnvironmentalFactors(void)
{
this->CalculateEnvironmentalCoefficient();
}

void EnvironmentalFactors ::CalculateEnvironmentalCoefficient (void)
{
this->EnvironmentalCoefficient = this-
>CurrentTerrain.GetTerrainCoefficient() * this-
>CurrentWeather.GetWeatherConditionsCoefficient();
}

double EnvironmentalFactors ::GetEnvironmentalCoefficient (void)
{
return this->EnvironmentalCoefficient;
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
class RaceCoordinator
{
private:
Runner Runners[10];
double RaceTimeToScaleFactor;
double CalculateRaceTimePerRunner(Runner);
char* GetRunnersName (Runner);
double GetRaceTimePerRunner(Runner);
public:
RaceCoordinator(void);
char* GetRunnersNameByIndex(int);
double GetRaceTimePerRunnerByIndex(int);
};

RaceCoordinator::RaceCoordinator(void)
{
this->Runners[0].InitializeRunner("Mary", 22, 0.9);
this->Runners[1].InitializeRunner("Joe", 34, 0.75);
this->Runners[2].InitializeRunner("Nick", 30, 0.8);
this->Runners[3].InitializeRunner("Tim", 19, 0.95);
this->Runners[4].InitializeRunner("Suzy", 40, 0.6);
this->Runners[5].InitializeRunner("Martha", 48, 0.6);
this->Runners[6].InitializeRunner("Kris", 25, 0.8);
this->Runners[7].InitializeRunner("Matt", 27, 0.5);
this->Runners[8].InitializeRunner("Jerrod", 39, 0.65);
this->Runners[9].InitializeRunner("James", 32, 0.85);

this->RaceTimeToScaleFactor = 200;
}

double RaceCoordinator ::CalculateRaceTimePerRunner (Runner _Runner)
{
return (this->RaceTimeToScaleFactor) *
_Runner.GetRunningCapability();
}

double RaceCoordinator ::GetRaceTimePerRunner (Runner _Runner)
{
return this->CalculateRaceTimePerRunner(_Runner);
}

double RaceCoordinator ::GetRaceTimePerRunnerByIndex (int i)
{
return this->GetRaceTimePerRunner(this->Runners[i]);
}

char* RaceCoordinator ::GetRunnersName (Runner _Runner)
{
return _Runner.GetRunnersName();
}

char* RaceCoordinator ::GetRunnersNameByIndex (int i)
{
return this->GetRunnersName(Runners[i]);
}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
class RunProgram
{
private:
RaceCoordinator raceCoordinator();
EnvironmentalFactors raceEnvironmentalFactors();
public:
RunProgram();
void Run(void);
};

RunProgram::RunProgram(void)
{}

void RunProgram :: Run(void)
{
cout << "The race results are:" << endl;
cout << "Name \t\t Time" << endl;

for (int i = 0; i <= 9; ++i)
{
cout << this->raceCoordinator.GetRunnersNameByIndex(i) << "\t\t" <<
this->raceCoordinator.GetRaceTimePerRunnerByIndex(i) / this-
>raceEnvironmentalFactors.GetEnvironmentalCoefficient() << endl;
}
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Ian Collins

unread,
Jul 20, 2008, 3:26:57 AM7/20/08
to
Kush wrote:
> Hello,
>
> I am attempting to create a small program to teach a colleague how to
> program using C++ but I seem to be having my own difficulties with a
> compile error. It has been quite some time since I last wrote code in
> general, led alone in C++.
>
> I was wondering if someone wouldn't mind pointing out the source of my
> problem. :)
>
> The compile error I am getting is below and occurs in the
> RunProgram :: Run method definition
>
> error C2228: left of '.GetRunnersNameByIndex' must have class/struct/
> union type
> error C2228: left of '.GetRaceTimePerRunnerByIndex' must have class/
> struct/union type
> error C2228: left of '.GetEnvironmentalCoefficient' must have class/
> struct/union type
>
raceCoordinator (the bit on the left) is a function.

--
Ian Collins.

Seungbeom Kim

unread,
Jul 20, 2008, 3:22:40 AM7/20/08
to
Kush wrote:
> The compile error I am getting is below and occurs in the
> RunProgram :: Run method definition
>
> error C2228: left of '.GetRunnersNameByIndex' must have class/struct/
> union type
> error C2228: left of '.GetRaceTimePerRunnerByIndex' must have class/
> struct/union type
> error C2228: left of '.GetEnvironmentalCoefficient' must have class/
> struct/union type

[snipped]

> this->raceCoordinator.GetRunnersNameByIndex(i)
> this->raceCoordinator.GetRaceTimePerRunnerByIndex(i)
> this->raceEnvironmentalFactors.GetEnvironmentalCoefficient()

raceCoordinator and raceEnvironmentalFactors are functions. You are
applying Get...() member functions on the functions themselves, not
the class objects returned from the function calls. Append pairs of
parentheses '()' to get the results of the function calls, not the
functions themselves.

--
Seungbeom Kim

ppizzq

unread,
Jul 20, 2008, 8:28:28 AM7/20/08
to
On 7?20?, ??3?22?, Seungbeom Kim <musip...@bawi.org> wrote:
> Kush wrote:
> > The compile error I am getting is below and occurs in the
> > RunProgram :: Run method definition
>
> > error C2228: left of '.GetRunnersNameByIndex' must have class/struct/
> > union type
> > error C2228: left of '.GetRaceTimePerRunnerByIndex' must have class/
> > struct/union type
> > error C2228: left of '.GetEnvironmentalCoefficient' must have class/
> > struct/union type
>
> [snipped]
>
> > this->raceCoordinator.GetRunnersNameByIndex(i)
> > this->raceCoordinator.GetRaceTimePerRunnerByIndex(i)
> > this->raceEnvironmentalFactors.GetEnvironmentalCoefficient()
>
> raceCoordinator and raceEnvironmentalFactors are functions. You are
> applying Get...() member functions on the functions themselves, not
> the class objects returned from the function calls. Append pairs of
> parentheses '()' to get the results of the function calls, not the
> functions themselves.

{ Edits: quoted signature and clc++m banner removed, please don't quote them
(the clc++m banner is appended to every article, including this one). -mod }

in class RunProgram you define a memeber function named
raceCoordinator without arguments and with RaceCoordinator type
return value, not a member varible; you should write :
private :
RaceCoordinator raceCoordinator ;


--

ppizzq

unread,
Jul 20, 2008, 9:28:12 AM7/20/08
to
this line is the error:
private:
RaceCoordinator raceCoordinator();

you define a function named raceCoordinator which has no arguments and
return a RaceCoordinator value type;

you should write :

priviate :
RaceCoordinator raceCoordinator;

--

Alberto Ganesh Barbati

unread,
Jul 20, 2008, 9:28:13 AM7/20/08
to
Kush ha scritto:

>
> double RaceCoordinator ::CalculateRaceTimePerRunner (Runner _Runner)
> {
> return (this->RaceTimeToScaleFactor) *
> _Runner.GetRunningCapability();
> }

Identifier names beginning with an underscore and an uppercase letter
are reserved to the implementation in the global namespace. Even if you
are not using _Runner in the global namespace, so you are not violating
anything, I would choose a different name anyway.

> class RunProgram
> {
> private:
> RaceCoordinator raceCoordinator();
> EnvironmentalFactors raceEnvironmentalFactors();

These lines are declaring functions, not data members. Is that your
intention? If you wanted data members you must remove the "()".

> public:
> RunProgram();
> void Run(void);
> };
>
> RunProgram::RunProgram(void)
> {}

The use of "(void)" is provided for backward compatibility with C and is
frowned upon in a C++ program. Just write "()".

>
> void RunProgram :: Run(void)
> {
> cout << "The race results are:" << endl;
> cout << "Name \t\t Time" << endl;
>
> for (int i = 0; i <= 9; ++i)
> {
> cout << this->raceCoordinator.GetRunnersNameByIndex(i) << "\t\t" <<
> this->raceCoordinator.GetRaceTimePerRunnerByIndex(i) / this->
> raceEnvironmentalFactors.GetEnvironmentalCoefficient() << endl;
> }
> }

In the expression

this->raceCoordinator.GetRunnersNameByIndex(i)

this->raceCoordinator is not a object, so it can't be on left side of
"." If you intended you call the function instead you had to insert
"()" as in:

this->raceCoordinator().GetRunnersNameByIndex(i)

by the way, the "this->" part is implicit and can be omitted.


HTH,

Ganesh

Seungbeom Kim

unread,
Jul 20, 2008, 8:07:10 PM7/20/08
to
Alberto Ganesh Barbati wrote:
> Kush ha scritto:

>>
>> RunProgram::RunProgram(void)
>> {}
>
> The use of "(void)" is provided for backward compatibility with C and is
> frowned upon in a C++ program. Just write "()".

I have wondered, why is it frowned upon in a C++ program? I don't see
any harm there. Did I miss anything? Is it deprecated or anything?

Actually it may even be better in a header file shared by C and C++,
because it means exactly the same thing both in C and C++: both f() and
f(void) in C++ means f(void) in C, but f() in C means something else.
In addition, in a sense, it's more consistent across the parameter list
and the return type ("use void to mean nothing").

I know we really don't have to type the four additional characters,
but I don't see the point in bothering to point out that it shouldn't
be used. If there's any, can you please explain it?

--
Seungbeom Kim

Alberto Ganesh Barbati

unread,
Jul 21, 2008, 4:40:18 PM7/21/08
to
Seungbeom Kim ha scritto:

> Alberto Ganesh Barbati wrote:
>> Kush ha scritto:
>>>
>>> RunProgram::RunProgram(void)
>>> {}
>>
>> The use of "(void)" is provided for backward compatibility with C and is
>> frowned upon in a C++ program. Just write "()".
>
> I have wondered, why is it frowned upon in a C++ program? I don't see
> any harm there. Did I miss anything? Is it deprecated or anything?

It's not deprecated. I simply consider it a bad programming style. You
may disagree, but there are people who doesn't.

> Actually it may even be better in a header file shared by C and C++,
> because it means exactly the same thing both in C and C++: both f() and
> f(void) in C++ means f(void) in C, but f() in C means something else.

Well, to share a header between a C and C++ program the header will
definitely need to have an extern "C" somewhere. For functions with C
linkage it may actually make sense. However, it's more than six years
that I don't write a C program nor that I need to write a header that
might be shared with a C program, so why should I care?

> In addition, in a sense, it's more consistent across the parameter list
> and the return type ("use void to mean nothing").

I disagree. While the void keyword in a parameter list means "nothing
here", the void keyword used as return type means "calling this function
evaluates to an expression of type void". In other words: it is
*something* of type void, not *nothing*.

By the way, the "(void)" notation is a hack even in C, to work around
the initial mistake of allowing "()" to mean "the list of arguments is
unknown". In C++ they did no such mistake and "no parameters" is always
represented with "()" in all contexts. If you want to call a function
with no parameters you can't use "f(void)", can you?

> I know we really don't have to type the four additional characters,
> but I don't see the point in bothering to point out that it shouldn't
> be used. If there's any, can you please explain it?

As I say, it's just a matter of programming style. De gustibus non est
disputandum.

Ganesh

--

Jiang

unread,
Jul 24, 2008, 7:12:04 AM7/24/08
to
Well, if this post is not that off-posting ...

> I have wondered, why is it frowned upon in a C++ program? I don't see
> any harm there. Did I miss anything? Is it deprecated or anything?
>

Here I agree with Alberto that using void for empty parameter list in
C++ is not a good programming style.

For the following C++ code

void foo(void){}

I always wondering how much the writer knows the C++ language.
(and, yes, it does cost 4 extra typing )

Of course, it is an issue of style, YMMV. :-)


> Actually it may even be better in a header file shared by C and C++,
> because it means exactly the same thing both in C and C++: both f() and
> f(void) in C++ means f(void) in C, but f() in C means something else.
> In addition, in a sense, it's more consistent across the parameter list
> and the return type ("use void to mean nothing").

IMHO, header file is not an issue there.

Mixing C and C++ requires quite a lot extra work and add the void
only won't help at all for the real-world code. And, even if we must
to mix C and C++, since the void is a must for C and it is better
style to use empty parentheses to distinguish C++ code from C
code, IMHO.

BTW, in C99, function declarator with empty parentheses is now
an obsolescent feature (6.11.6). It is a good news since less
confusion will be made in the future for this issue.

> I know we really don't have to type the four additional characters,
> but I don't see the point in bothering to point out that it shouldn't
> be used. If there's any, can you please explain it?

The only point I can think of is, well, protecting our fingers and
keyboard :-) , but as you mentioned above, why don't we do the
same job using the simple way?

Jiang


--

Erik Max Francis

unread,
Jul 24, 2008, 6:08:13 PM7/24/08
to
Seungbeom Kim wrote:

> Alberto Ganesh Barbati wrote:
>> Kush ha scritto:
>>>
>>> RunProgram::RunProgram(void)
>>> {}
>>
>> The use of "(void)" is provided for backward compatibility with C and is
>> frowned upon in a C++ program. Just write "()".
>
> I have wondered, why is it frowned upon in a C++ program? I don't see
> any harm there. Did I miss anything? Is it deprecated or anything?
>
> Actually it may even be better in a header file shared by C and C++,
> because it means exactly the same thing both in C and C++: both f() and
> f(void) in C++ means f(void) in C, but f() in C means something else.
> In addition, in a sense, it's more consistent across the parameter list
> and the return type ("use void to mean nothing").
>
> I know we really don't have to type the four additional characters,
> but I don't see the point in bothering to point out that it shouldn't
> be used. If there's any, can you please explain it?

The most useful answer would be that the inventor of the language
intended the empty argument list to mean an empty argument list, not an
unspecified argument list (as it is in C). Thus the argument list
`(void)` is unnecessary and included only for C compatibility.

Scanning through _The C++ Programming Language_ 3e, you'd be hard
pressed to find Stroustrup even mentioning the backward-compatibility
syntax. A quick scan through _Design and Evolution of C++__ also
doesn't seem to think it significant enough to warrant mention. It's of
course indicated in the C++ Standard (8.3.5/2), but only in one sentence
without fanfare. And the vast majority of the examples in all three
books use the empty argument list syntax, not `(void)`.

--
Erik Max Francis && m...@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis
Grub first, then ethics.
-- Bertolt Brecht

Seungbeom Kim

unread,
Jul 24, 2008, 6:08:14 PM7/24/08
to
Jiang wrote:
>> I have wondered, why is it frowned upon in a C++ program? I don't see
>> any harm there. Did I miss anything? Is it deprecated or anything?
>>
>
> Here I agree with Alberto that using void for empty parameter list in
> C++ is not a good programming style.

And I asked why.

>
> For the following C++ code
>
> void foo(void){}
>
> I always wondering how much the writer knows the C++ language.
> (and, yes, it does cost 4 extra typing )

If only it were that easy to know enough about the C++ language... :D

>
> Of course, it is an issue of style, YMMV. :-)

Is it just that? Then why have I heard so many people tell others
not to use void for the empty parameter list?

>
>> Actually it may even be better in a header file shared by C and C++,
>> because it means exactly the same thing both in C and C++: both f() and
>> f(void) in C++ means f(void) in C, but f() in C means something else.
>

> IMHO, header file is not an issue there.
>
> Mixing C and C++ requires quite a lot extra work and add the void
> only won't help at all for the real-world code.

Neither did I mean nor did I say that it was just as easy as adding
"void" to mix C and C++. Don't worry, I know better than that. :)

> And, even if we must
> to mix C and C++, since the void is a must for C and it is better
> style to use empty parentheses to distinguish C++ code from C
> code, IMHO.

Again, why? This is another claim without a proof.
"To distinguish C++ code from C code" -- is it the reason?
Why do we have to make the distinction, then?

>
> BTW, in C99, function declarator with empty parentheses is now
> an obsolescent feature (6.11.6). It is a good news since less
> confusion will be made in the future for this issue.

That means future C programs will be more likely to write
f(void) instead of f(). I don't think that counts as a reason
for C++ programmers to prefer f() to f(void).

>
>> I know we really don't have to type the four additional characters,
>> but I don't see the point in bothering to point out that it shouldn't
>> be used. If there's any, can you please explain it?
>
> The only point I can think of is, well, protecting our fingers and
> keyboard :-) , but as you mentioned above, why don't we do the
> same job using the simple way?

If the only point is to protect our fingers and keyboard, there should
be absolutely no point in writing sentences and paragraphs and articles
to tell others not to use void and/or discuss why not. I suspect there
should be other reasons.

--
Seungbeom Kim

0 new messages