phat.obj : error LNK2005: "class clEzWin * clCallBack"
(?clCallBack@@3PAVclEzWin@@A) already defined in ezwin.obj
the header file( ezwin.h ) is:
#ifndef __EZWIN_H__
#define __EZWIN_H__
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class clEzWin
{
//class defined
};
void EZ_SetCallBack( clEzWin *clPoint );
LRESULT CALLBACK EZ_MainProc( HWND hMain , UINT uiMsg , WPARAM wpmArg ,
LPARAM lpmArg );
clEzWin *clCallBack;
#endif // __EZWIN_H__
The source file just declares all the functions and includes the header
file. Like this:
#include "ezwin.h"
The "ezwin.h" is included through another file( phat.h ). If anyone know
why the linker is giving me all these errors, I would really appreciate
it, cheers. If you need anymore info, then I will be happy to provide
it, cheers again.
--
???_blue's current PokéDEX stats...
Seen : 93
Owned : 30
S.Note: a Pikachu & Snorlax
"ezwin.h" declares:
clEzWin *clCallBack;
so if ezwin.h is #included in any way in more than one source file you
will have a multiple declarations link error.
Which means that you should replace
clEzWin *clCallBack;
with
extern clEzWin *clCallBack;
in ezwin.h, and then put
clEzWin *clCallBack;
in your ezwin.cpp
Sent via Deja.com http://www.deja.com/
Before you buy.
> Which means that you should replace
>
> clEzWin *clCallBack;
>
> with
>
> extern clEzWin *clCallBack;
>
> in ezwin.h, and then put
>
> clEzWin *clCallBack;
>
> in your ezwin.cpp
Now it all makes sense, I now know the point of the extern keyword now,
cheers.
Since you're just getting into this, consider the following
methodology for dealing with 'extern':
myglobals.h
#ifdef __MAIN__
#define GLO(x,v) x v
#else
#define GLO(x,v) extern x
#endif
GLO(int x,);
GLO(float scale,=123.456);
GLO(bool drawbackground,=false);
main.cpp
#define __MAIN__
#include "myglobals.h"
anothermodule.cpp
#include "myglobals.h"
someothermodule.cpp
#include "myglobals.h"
This concentrates your variable definition in a SINGLE
myglobals.h file and makes it easy to modify. When compiled,
only main.cpp will see the variable declaration (and optional
value). All other modules will only see 'extern'.
Otherwise, there's nothing to stop you from doing silly things
like this:
main.cpp
int x;
char title[100];
someothermodule.cpp
extern float x; // wrong
extern char *title; // also wrong
You're just asking for trouble when you spread definitions
and 'extern' across multiple modules.
--
John A. Grant * I speak only for myself * (remove 'z' to reply)
Radiation Geophysics, Geological Survey of Canada, Ottawa
If you followup, please do NOT e-mail me a copy: I will read it here
In fact, it only saves you the trouble of modifying multiple files if you
change the type of the variable - changing the name will, ofcourse, still
require you to modify everything else and the initial value is set in the
.cpp. Besides, GLO(int x,) and GLO(float scale,=123.456) are not exactly
elegant or easy to read, are they? I think you'd get more typos with this
approach than linker errors without it. But again, this is just what I
think, as a macrophobic :-)
X.
* Sent from RemarQ http://www.remarq.com The Internet's Discussion Network *
The fastest and easiest way to search and participate in Usenet - Free!
You and Xazziri are so right. I'm 100% smoke & mirrors and I
don't have a single clue about anything. In fact, I'm a pretty lame
programmer and I rely almost entirely on "macro-magic" to
get anything done. Since my primary goal is to impress and
since I can't do it on the basis of my knowledge and code-writing
abilities, the only way I can impress people is with my use of
macros. In fact, all of the code I write is crap - it's completely
unreadable and completely unmaintainable.
Regards,
Harold Weissfield
"John A. Grant" <zjag...@znrcanz.gcz.ca> wrote in message
news:8d0no9$du...@nrn2.NRCan.gc.ca...
(my response is not directed specifically to Harold, but
I will focus on his theme of "styles and preferences" and
"ease of use")
I fully recognize that there are many different styles of coding
and that a style which is appropriate for some people may
not be for others. However, the two comments I received were
absolute comments about the technique, not relative comments,
comparing style or technique X versus Y. Furthermore, they
were not constructive, offering no alternate solutions that were
better or which solved perceived weaknesses in the solution I
presented.
There are legitimate uses of macros and it's one of the strengths
of the C language. Features of any language can be used
appropriately and they can be abused (i.e. "go to" in ANSI
66-era FORTRAN programs). A certain amount of macrophobia
is a good thing, because macros can be used to write unreadable
and unmaintainable code. For C++, inline functions are preferred
to the use of macros.
Also, it's one thing to use macros in static declarations like
this and it's quite another to use macros in place of functions.
How many times have you seen macros like this:
#define XXX(a,b,c,d,e) \
some expression \
and another expression \
and yet another expression \
still more stuff here \
and here \
and here
Then the macro is used like this:
if(XXX(....)) ...
Now *THAT* is unreadable and unmaintainable and represents
a clear abuse of macros and a certain amount of laziness.
Presumably someone could make a case for using macros to
generate in-line code like the above for use in real-time apps
for which function calling overhead is problematic. But it's
absurd to compare my technique for managing global
variables to this macro abuse.
I don't think that the technique I presented is an abuse of the
language and it certainly is not at the expense of readability
or maintainability. The advantage of having a SINGLE file
that contains only a SINGLE instance of the definition AND
initialization of a global variable makes the technique stand
head and shoulders over any other that I have seen.
BTW, I say "my technique", but I take no credit for 'inventing'
it. It's a technique that is used by many people.
One of the strengths of programmers is their ability to adapt
to different ideas. You can take a method or technique
which has some appeal, but which offends your sensibilities
somewhat and modify it and make it your own. For example:
Xazziri, you said:
"...Besides, GLO(int x,) and GLO(float scale,=123.456)
are not exactly elegant or easy to read, are they?"
and yet you didn't provide your (presumably better) solution
to be considered alongside mine. Perhaps you didn't like
the use of 2 variables in the macro. Ok, so adapt the
technique and use this:
#ifdef __MAIN__
#define GLO(x) x
#else
#define GLO(x) extern x
#endif
GLO(int x);
GLO(float y);
Presumably, this does not offend you as much. Given that
this is less offensive and therefore more acceptable to you,
the next step for you is to provide a way of initializing the global
variable. Note that it must be "elegant and easy to read", to
use your own words. However, from your comment:
"...the initial value is set in the .cpp."
I can only conclude that you didn't read or fully understood
the technique I was presenting, did you? Do you really
think that the value is initialized in the .cpp file? On the
contrary, the value is initialized in the .h file, during only
one instance of the #include
Macros are always 'magic'. But are they 'pointless' in this case?
Hardly. I have seen way too many instances of mismatches
that have been created because of a lack of organization (and
understanding) by C programmers. For example:
(a) "int x" versus "extern float x" and "extern int x"
(b) "char title[100]" versus "extern char *title"
(c) "int x=100" versus "int x=200"
Error (c) will be evident at link time, but errors (a) and (b)
are very difficult to find without scouring all of the code.
A simple technique that eliminates this potential error
can be invaluable to everyone.
Why do you think we put all of our function prototypes
in a single 'include' file instead of manually coding
prototypes (or using obsolete K&R syntax) in the
individual .c files? Using a single *.h file ensures a
consistent and uniform definition of the interface to
the function. I don't see any reason to not use the
same technique to provide the same interface to
global variables.
I have also seen way too much code that has hundreds
of 'extern' statements scattered throughout the code - a
nightmare of maintenance, as I'm sure you will agree.
You also said
"silly things' can only happen if modules start externing
symbols on their own instead of just including the .h file.
Unfortunately, you can't MAKE people include the header"
Duh, well you can't actually MAKE people do anything.
This is your own programming project - you can also disable
every warning and error message on your compiler and you
can refuse to use #define STRICT and you can also refuse
to check the return values of API functions. You can refuse
to check for NULL pointers. It's entirely up to you, of course.
The technique I presented, is a technique that I've used for
over 20 years. It's also a technique that is used (in various
forms) by MANY programmers. If you think it's silly, then you
don't have to use it, but if you're going to pronounce it 'pointless',
then you should be prepared to come up with something better.
This is a discussion forum for techniques and we can all learn
something from someone else. I'm quite prepared to learn a
new technique from you or anyone else, but I'm really not
interested in reading unfounded and gratuitous comments
like "pointless macro-magic".
I was not so presumptuous to claim that I have a better solution. I simply
think the existing language mechanism (extern <variable> in the header, real
declaration in the .cpp) is readable and sufficient.
> Perhaps you didn't like
> the use of 2 variables in the macro. Ok, so adapt the
> technique and use this:
> #ifdef __MAIN__
> #define GLO(x) x
> #else
> #define GLO(x) extern x
> #endif
> GLO(int x);
> GLO(float y);
>
> Presumably, this does not offend you as much. Given that
> this is less offensive and therefore more acceptable to you,
> the next step for you is to provide a way of initializing the global
> variable. Note that it must be "elegant and easy to read", to
> use your own words. However, from your comment:
> "...the initial value is set in the .cpp."
>
See above. Personally, I would use your first version if I used a macro at
all, because this one (and please don't be offended, but I can't resist) is
even more silly. This only aids the programmer who can't get his .cpp to
correspond with his .h properly. Mind you, that's one .cpp and one .h, it
won't have anything to do with any other .cpp's. What I meant was that I
didn't like the syntax of the macro. GLO(int x,) and GLO(float
scale,=123.456) look very strange to me as a run-of-the-mill C++ programmer.
I guess you get used to it.
> I can only conclude that you didn't read or fully understood
> the technique I was presenting, did you? Do you really
> think that the value is initialized in the .cpp file? On the
> contrary, the value is initialized in the .h file, during only
> one instance of the #include
>
No, no, I was talking about the language mechanism again, not your
technique. It got messed up in several edits, and I was careless enough not
to re-read my post properly. Apologies, but this was certainly not what I
meant to say. Oh, I give such good impressions of a moron I sometimes
convince myself. :-)
> Macros are always 'magic'. But are they 'pointless' in this case?
> Hardly. I have seen way too many instances of mismatches
> that have been created because of a lack of organization (and
> understanding) by C programmers. For example:
> (a) "int x" versus "extern float x" and "extern int x"
> (b) "char title[100]" versus "extern char *title"
> (c) "int x=100" versus "int x=200"
>
> Error (c) will be evident at link time, but errors (a) and (b)
> are very difficult to find without scouring all of the code.
> A simple technique that eliminates this potential error
> can be invaluable to everyone.
>
Ah, and this is the key point, I think. Unless two different people work on
the same module (I mean: one person works on the .h, the other on the .cpp),
how can you get your definitions confused? If people include your header,
the definition will be correct. If they don't, well, bad luck, there's
nothing you can do about that. I find it difficult to believe that people
who would get confused using 'extern' would get less confused using macros.
> Why do you think we put all of our function prototypes
> in a single 'include' file instead of manually coding
> prototypes (or using obsolete K&R syntax) in the
> individual .c files? Using a single *.h file ensures a
> consistent and uniform definition of the interface to
> the function. I don't see any reason to not use the
> same technique to provide the same interface to
> global variables.
>
Exactly! Couldn't agree with you more. The header provides the definition,
the .cpp provides the declaration. This goes for prototypes, why not for
global variables? If I paraphrased your technique for functions (and
ofcourse I'm not serious about this), it would be a little like this:
#ifdef __MAIN__
#define GLOFUNC(x,y) x { y }
#else
#define GLOFUNC(x,y) x;
#endif
GLOFUNC(int foo(int bar),
return bar * bar;
)
Wouldn't this ensure that you only need to define a function once, and
update it only in one location? I know the comparison is not quite fair, but
this is the main idea.
> I have also seen way too much code that has hundreds
> of 'extern' statements scattered throughout the code - a
> nightmare of maintenance, as I'm sure you will agree.
>
Absolutely. I've only had the misfortune of deciphering code like that a few
times, but it was enough to make me never want to do it again.
> "silly things' can only happen if modules start externing
> symbols on their own instead of just including the .h file.
> Unfortunately, you can't MAKE people include the header"
>
> Duh, well you can't actually MAKE people do anything.
> This is your own programming project - you can also disable
> every warning and error message on your compiler and you
> can refuse to use #define STRICT and you can also refuse
> to check the return values of API functions. You can refuse
> to check for NULL pointers. It's entirely up to you, of course.
>
Erm... I think we're getting off track here. I meant 'Unfortunately, you
can't MAKE people include the header instead of using 'extern <symbol>' in
their own .cpp.
PS. You managed to disable every error message? Great! Could you share that
trick with me? It would save me a lot of debugging time. :-) Just kidding,
ofcourse!
> The technique I presented, is a technique that I've used for
> over 20 years. It's also a technique that is used (in various
> forms) by MANY programmers. If you think it's silly, then you
> don't have to use it, but if you're going to pronounce it 'pointless',
> then you should be prepared to come up with something better.
>
> This is a discussion forum for techniques and we can all learn
> something from someone else. I'm quite prepared to learn a
> new technique from you or anyone else, but I'm really not
> interested in reading unfounded and gratuitous comments
> like "pointless macro-magic".
>
To make everything completely clear:
- I do not question your programming capabilities.
- I do not question the fact that people use this technique.
- I do not propose a technique of my own, I was merely trying to state the
opinion that the existing language features are sufficient and that the
inconvenience of learning the macro does not justify the benefits.
I hope this clears everything up.
X.
I use this technique since the beginning of my
programmer's career, and must agreee too !
> The header provides the definition,
> the .cpp provides the declaration.
NOooooo !
The header file must contain the declaration,
and the .c / .cpp file the definition !
>This goes for prototypes, why not for
> global variables?
And *this* is the real argument; the two
things should treat in the same manner.
--
Klaus-Werner Konrad
(ohne pfiffigen Spruch)
I am a sh*t-disturber by nature and couldn't resist seeing what
kind of reaction I'd get. From now on I'll refrain from making
those kind of comments. While they may not apply to you
personally, my comments are a result of many years of frustration
on my part, working with the kind of people I described in my
previous post.
>"Rude Dog" <rude-dog...@home.com.invalid> wrote in message
>news:108695f7...@usw-ex0102-016.remarq.com...
>> I agree 100% with your comments regarding macros. Unfortunately,
>> many programmers would much rather try to impress us all with
>> their nifty little tricks than to write readable, maintainable
>> code.
>
> You and Xazziri are so right. I'm 100% smoke & mirrors and I
> don't have a single clue about anything. In fact, I'm a pretty lame
> programmer and I rely almost entirely on "macro-magic" to
> get anything done.
<snip>
:-)
Don't tell the boss...
I'm with you on this one.
I used macros recently to get all the function pointers from the open
gl dll, and they came in mighty handy as there are 362 of the little
buggers.
They have their place.
Jimbo
--
@ Derbyshire
I see some ... words ahve been exchanged over this issue.
> myglobals.h
> #ifdef __MAIN__
> #define GLO(x,v) x v
> #else
> #define GLO(x,v) extern x
> #endif
> GLO(int x,);
> GLO(float scale,=123.456);
> GLO(bool drawbackground,=false);
>
> main.cpp
> #define __MAIN__
> #include "myglobals.h"
Eeep.
Knowing as I do the difference between declarations and definitions I would
tend to avoid this - not because of any misplaced :) macrophobia but because
damnit - once alls said and done you have definitions in the header file.
Given your requirement elsewhere on this thread that those who critisize
your method should produce an alternative though, I go the other way
entirely and say damn it - if you are going to define something in a header
file do it properly! Presented for your inspection is __declspec(selectany).
Guard a difinition of anything with this (Assuming you ahve MSVC 6) and the
linker will happily find and use the first definition it finds and throw
away the rest.
myglobals.h can then, with complete impunity, contain lines such as:
extern __declspec(selectany) int x3=3;
The link errors encountered that originated this thread would never occour.
In addition - the item is defined but once and declared independtly never.
Those amongst us who are macro minded could I suppose turn the line into a
much more compact:
GLO int x3=3;
Simple, compact, hard to screw up, and entirely specific to Microsoft. (The
definition of GLO in this case is left as an excercise to the reader).
Chris
--
VisualC++ & Win32 FAQ: http://www.mvps.org/vcfaq
My Win32 Page: http://www.mvps.org/user32
> I was not so presumptuous to claim that I have a better solution. I simply
> think the existing language mechanism (extern <variable> in the header,
real
> declaration in the .cpp) is readable and sufficient.
For you maybe, but lesser, sloppier programmers are
presented endless opportunities to mess it up. There
was a case here where a novice programmer thought
that "char x[100]" and "extern char *" were exactly the same.
Most people can benefit from the reduction of multiple
declarations into a single declaration.
[...]
> Ah, and this is the key point, I think. Unless two different people work
on
> the same module (I mean: one person works on the .h, the other on the
.cpp),
> how can you get your definitions confused? If people include your header,
> the definition will be correct. If they don't, well, bad luck, there's
> nothing you can do about that. I find it difficult to believe that people
> who would get confused using 'extern' would get less confused using
macros.
If a single person was working even on a moderate size
project (perhaps ~200k loc), and using explicit "extern"
in all of the modules, it's very easy to get it screwed up.
For example, you might start off with:
main.cpp
int scale=123;
the remainder of the *.cpp files:
extern int scale;
Then one day, you realize that you need a 'float' scale, so
now you have to make changes in EVERY SINGLE FILE:
main.cpp
float scale=123;
*.cpp
extern float scale;
Not only does that waste a lof of time, if you screw up and
miss just one of those 'extern' statements, you will mess
up the entire project and it will be very difficult to track
down. I'm not talking about 3 source files here - I'm talking
about 500+ source files. Grep can only take you so far.
[...]
> Erm... I think we're getting off track here. I meant 'Unfortunately, you
> can't MAKE people include the header instead of using 'extern <symbol>' in
> their own .cpp.
If I was working on a project with other people and the global.h
was provided for me, I can't imagine why I wouldn't use it. I
would never copy definitions from it. Anyone who is used to
#include would do that. Good C programmers never copy
things from *.h files - just the VB folks.
> - I do not propose a technique of my own, I was merely trying to state the
> opinion that the existing language features are sufficient and that the
> inconvenience of learning the macro does not justify the benefits.
Yes, the features of the language are 'sufficient' to get the
job done. But judicious use of macros can provide a more
robust development environment that will help you get the
job done even better, more reliably and with less code
maintenance requirements. Nobody (?) would question
that STRICT is good for programmers and for the products
they create. I say the same about 'GLO'.
> Eeep.
> Knowing as I do the difference between declarations and definitions I
would
> tend to avoid this - not because of any misplaced :) macrophobia but
because
> damnit - once alls said and done you have definitions in the header file.
[...]
> file do it properly! Presented for your inspection is
__declspec(selectany).
>
> Guard a difinition of anything with this (Assuming you ahve MSVC 6) and
the
> linker will happily find and use the first definition it finds and throw
> away the rest.
> myglobals.h can then, with complete impunity, contain lines such as:
>
> extern __declspec(selectany) int x3=3;
But, to use your own words. "once all's said and done, you
have definitions in the header file. It's the same problem
you had with my version. I don't see that it's a problem either
way. My method prevents you from having multiple
initializations. Ok, you could do something stupid like
#define __MAIN__ in more than one module. But the linker
will trap that error. I think I would rather hand a linker
report multiple values, than have the linker "use the first
definition it finds and throw away the rest".
Hmm, a better naming convention is:
#define __XXX__
#include "xxx.h"
so the #define matches the filename.
[...]
> Simple, compact, hard to screw up, and entirely specific to Microsoft.
(The
> definition of GLO in this case is left as an excercise to the reader).
I don't see hardly any difference between the two methods.
1. both methods have the 'extern' and the initialization value
in the same *.h file.
2. both prevent linker errors
3. both are "simple, compact and hard to screw up"
The only difference I can see is that mine is completely
generic and works with any compiler and is 100% ANSI C.
Your method requires a Microsoft compiler.
John, the point I was trying to make was that you should have the 'extern
int/float scale' in ONE file, and one file only: main.h, like this:
main.h:
#ifndef MAIN_H
#define MAIN_H
// Function prototypes here
extern float scale;
#endif
main.cpp:
#include "main.h"
float scale = 0.0f;
othermod.cpp:
#include "main.h"
// use scale here
And indeed, people who then choose to go 'extern' on their own instead of
properly including main.h like a good little programmer deserve all the
trouble they can get. The only thing I am trying to say and to which I see
we both agree, really, is this:
Thou shalt not use 'extern' in thy own .cpp files but use the header(s)
supplied by the module's author, lest thou be smitten by the combined wrath
of the compiler, being the judge, and the linker, being the executioner.
And whether you then use macros or not is a matter of personal opinion. I
personally don't like it, but if it works, I say live and let live.
X.
So you have
globals.h:
extern int scale;
main.cpp:
#include "globals.h"
int scale = 123;
the remainder of the *.cpp files:
#include "globals.h"
BTW: I personally use an own file
for global variables with the name
globals.c / .cpp in my projects.
> Then one day, you realize that you need a 'float' scale, so
> now you have to make changes in EVERY SINGLE FILE:
> main.cpp
> float scale=123;
> *.cpp
> extern float scale;
>
No, see above.
But in any case you have to make changes in every single
file that USES the variable 'scale' in most cases ...
>
[snip]
> John, the point I was trying to make was that you should have the 'extern
> int/float scale' in ONE file, and one file only: main.h, like this:
>
> main.h:
> #ifndef MAIN_H
> #define MAIN_H
> // Function prototypes here
> extern float scale;
> #endif
>
> main.cpp:
> #include "main.h"
> float scale = 0.0f;
>
> othermod.cpp:
> #include "main.h"
> // use scale here
>
> And indeed, people who then choose to go 'extern' on their own instead of
> properly including main.h like a good little programmer deserve all the
> trouble they can get.
Awww, just when I thought we were on the same wavelength,
you ruined it :) On one hand, we agree on ONE file, but you
only put half of the information in that file - the initialization is
in another file and *that* is the point on which we disagree
(and I think we are going to remain in disagreement0
The whole point of my GLO method is to keep everything in
one file - the data type, the 'extern' and the initialization value.
In your example above, if you decide one day to change
'scale' to a 'double', then you have to make a change in
each of 2 files:
(a) change 'extern float scale' to 'extern double scale'
(b) change 'float scale=0.0f' to 'double scale=0.0'
If you do NOT get both changes, you'll be screwed and
that is exactly the situation that is avoided by using my
GLO method.
>>The only thing I am trying to say and to which I see
> we both agree, really, is this:
> Thou shalt not use 'extern' in thy own .cpp files but use the header(s)
> supplied by the module's author, lest thou be smitten by the combined
wrath
> of the compiler, being the judge, and the linker, being the executioner.
Agreed.
> And whether you then use macros or not is a matter of personal opinion. I
> personally don't like it, but if it works, I say live and let live.
Ok.
> BTW: I personally use an own file
> for global variables with the name
> globals.c / .cpp in my projects.
Mine is called myapp.glo, partly because I use my GLO
macro, and partly because it's not really a .h and not really
a .cpp - it masquerades as both.
> > Then one day, you realize that you need a 'float' scale, so
> > now you have to make changes in EVERY SINGLE FILE:
> > main.cpp
> > float scale=123;
> > *.cpp
> > extern float scale;
> >
> No, see above.
Ok, not every file then. What I meant was that you have to
make the change in at least 2 places: the file with the 'extern'
and the file that initializes it (see Xazziri's latest example and
my comments).
> But in any case you have to make changes in every single
> file that USES the variable 'scale' in most cases ...
True enough - probably, especially if printing, i.e. "%d"
vs "%g".