Trying to make a struct external

S

Stefan

Hi,
I am trying to get my structure to be externed so I can use it in all
my
projects source files, but the code is generating errors. Here is some
of my
code:

"Globals.cpp"
typedef struct SPECKEY {
bool BeenUsed;
bool Pressed;
bool On;
} specialkey;

#include "globals.h"

specialkey IsShift, IsAlt, IsMod1, IsMod2, IsMod3; // line 24.
....

"Globals.h"
....
extern specialkey IsAlt;
extern specialkey IsShift;
extern specialkey IsMod1;
extern specialkey IsMod2;
extern specialkey IsMod3;
....

It generates the following errors:

Globals.h(77): error C2146: syntax error : missing ';' before
identifier
'IsAlt'
Globals.h(77): error C2501: 'IsAlt' : missing storage-class or type
specifiers
etc...

And the same errors for the other extern lines. I have tried leaving
out the
'specialkey' bit of the extern lines, but that generates the following
errors:

KeyEventSink.cpp(142): error C2228: left of '.On' must have
class/struct/union type
KeyEventSink.cpp(143): error C2228: left of '.Pressed' must have
class/struct/union
type
Globals.cpp(24): error C2371: 'IsShift' : redefinition; different basic
types
etc...

Does anyone know how I can make a structure externed without generating
errors? Thanks.
 
G

Gernot Frisch

"Globals.cpp"
typedef struct SPECKEY {
bool BeenUsed;
bool Pressed;
bool On;
} specialkey;

#include "globals.h"

specialkey IsShift, IsAlt, IsMod1, IsMod2, IsMod3; // line 24.

SPECKEY IsShift, IsAlt...
...

"Globals.h"
...
extern specialkey IsAlt;
extern specialkey IsShift;
extern specialkey IsMod1;
extern specialkey IsMod2;
extern specialkey IsMod3;

extern SPECKEY IsAlt;


struct STRUCTNAME
{
members;
} variable_of_type_STRUCTNAME;

HTH,
Gernot
 
R

Rolf Magnus

Stefan said:
Hi,
I am trying to get my structure to be externed so I can use it in all
my projects source files, but the code is generating errors. Here is some
of my code:

You have to put the struct definition into your header file.
"Globals.cpp"
typedef struct SPECKEY {
bool BeenUsed;
bool Pressed;
bool On;
} specialkey;

put the above into the header, not the .cpp file. And you can drop the
typedef. Just write:

struct specialkey {
bool BeenUsed;
bool Pressed;
bool On;
};
 
V

Victor Bazarov

Stefan said:
I am trying to get my structure to be externed so I can use it in all
my
projects source files, but the code is generating errors. Here is some
of my
code:

"Globals.cpp"
typedef struct SPECKEY {
bool BeenUsed;
bool Pressed;
bool On;
} specialkey;

#include "globals.h"

specialkey IsShift, IsAlt, IsMod1, IsMod2, IsMod3; // line 24.
...

"Globals.h"
...
extern specialkey IsAlt;
extern specialkey IsShift;
extern specialkey IsMod1;
extern specialkey IsMod2;
extern specialkey IsMod3;
...

It generates the following errors:

Globals.h(77): error C2146: syntax error : missing ';' before
identifier
'IsAlt'
Globals.h(77): error C2501: 'IsAlt' : missing storage-class or type
specifiers
etc...

And the same errors for the other extern lines. I have tried leaving
out the
'specialkey' bit of the extern lines, but that generates the following
errors:

KeyEventSink.cpp(142): error C2228: left of '.On' must have
class/struct/union type
KeyEventSink.cpp(143): error C2228: left of '.Pressed' must have
class/struct/union
type
Globals.cpp(24): error C2371: 'IsShift' : redefinition; different basic
types
etc...

Does anyone know how I can make a structure externed without generating
errors? Thanks.

While both suggestions from Gernot are valid and good, I don't think that
they will solve your problem. In your source code as you have posted it
you have (after inclusion):

typedef struct BLAH { bool flag; } blah;
extern blah a_blah, b_blah, c_blah; // this is in 'globals.h'
blah a_blah, b_blah, c_blah;

, essentially. It compiles fine, as it should. The error is apparently
due to the fact that some other header in 'globals.cpp' includes the
'globals.h' header _before_ the 'struct BLAH' is defined. That's what
the compiler is complaining about.

So, Rolf is right, put the struct definition into a header and include it
into 'globals.h' as well as in 'globals.cpp'. Make sure you have double
inclusion guards in it:
-------------------------------------------------- Speckey.h
#ifndef SPECKEY_INCLUDED
#define SPECKEY_INCLUDED

struct specialkey {
...
};

#endif
-------------------------------------------------- Globals.h
#ifndef GLOBALS_INCLUDED
#define GLOBALS_INCLUDED

#include <Speckey.h>

extern specialkey IsShift; // etc.

#endif
-------------------------------------------------- Globals.cpp
#include <Speckey.h>
#include <Globals.h> // if you have to

....
 
J

Jonathan Mcdougall

Victor said:
While both suggestions from Gernot are valid and good, I don't think that
they will solve your problem. In your source code as you have posted it
you have (after inclusion):

typedef struct BLAH { bool flag; } blah;
extern blah a_blah, b_blah, c_blah; // this is in 'globals.h'
blah a_blah, b_blah, c_blah;

, essentially. It compiles fine, as it should. The error is apparently
due to the fact that some other header in 'globals.cpp' includes the
'globals.h' header _before_ the 'struct BLAH' is defined. That's what
the compiler is complaining about.

So, Rolf is right, put the struct definition into a header and include it
into 'globals.h' as well as in 'globals.cpp'. Make sure you have double
inclusion guards in it:
-------------------------------------------------- Speckey.h
#ifndef SPECKEY_INCLUDED
#define SPECKEY_INCLUDED

struct specialkey {
...
};

#endif
-------------------------------------------------- Globals.h
#ifndef GLOBALS_INCLUDED
#define GLOBALS_INCLUDED

#include <Speckey.h>

# include "speckey.h"
extern specialkey IsShift; // etc.

#endif
-------------------------------------------------- Globals.cpp
#include <Speckey.h>
#include <Globals.h> // if you have to

# include "speckey.h"
# include "globals.h"

specialkey IsShift; // etc.
....
-------------------------------------------------------------

By the way, to the OP, globals are best avoided.
There surely is another way of doing that. If you
tell us a bit more about the way they are used, we
could give you a hand.


Jonathan
 
V

Victor Bazarov

Jonathan said:
# include "speckey.h"

First of all, you misspelled the header, the first letter of the file
name is an 'S' and not an 's'. Second, angle brackets or double quotes
are often interchangeable, and the use of them is implementation-defined
anyway. Third, the existence or absence of whitespace between '#' and
'include' is a personal preference. Considering all that, I do not see
how your "correction" is valid.
# include "speckey.h"
# include "globals.h"

Same here.
specialkey IsShift; // etc.



By the way, to the OP, globals are best avoided.

It is often pointless to give such recommendation without an explanation.
Care to provide one?
There surely is another
way of doing that. If you tell us a bit more about the way they are
used, we could give you a hand.

You can start by explaining why "globals are best avoided".

V
 
J

Jonathan Mcdougall

Victor said:
First of all, you misspelled the header, the first letter of the file
name is an 'S' and not an 's'.

That's true, but it may or may not matter, that's
implementation defined.
Second, angle brackets or double quotes
are often interchangeable,

How often, I wonder?
and the use of them is implementation-defined
anyway.

Also true, but a name between angle brackets does
not necessarily represent an actual source file
and it would be legal for an implementation to
reject these directives even if they worked with
double quotes. That's what most modern compilers do.

What point are you trying to make here?
Third, the existence or absence of whitespace between '#' and
'include' is a personal preference.

And of course wasn't the point of the "correction".
Considering all that, I do not see
how your "correction" is valid.
Seriously?


It is often pointless to give such recommendation without an explanation.

Here we go (in no particular order and non
exhaustive).

Because global objects can be accessed from
anywhere within a program, tracking every of their
use and predicting their state at a given point is
difficult.

Their order of construction (and therefore
destruction) is undefined across translation units
and the programmer must rely on several dirty
tricks to make sure one global object can use
another. These tricks are often non portable and
"inefficient".

The Singleton pattern has often been used as a
disguised global object and even if the access is
more secure (since it is done via a function), the
drawbacks are still the same.

Exceptions thrown by global objects are not catchable.

Finally, when two modules share a global object,
it makes it more difficult to reuse only one of them.

But don't get me wrong. I didn't say global
objects *must* be avoided, I said globals are best
avoided. There are some designs in which they are
preferable/more "efficient"/mandatory.
Care to provide one?

I would prefer the tone of the discussion to stay
(become?) friendly or at least polite :)


Jonathan
 
V

Victor Bazarov

X-no-archive: yes
Jonathan said:
Victor Bazarov wrote:

[...]
What point are you trying to make here?

Sorry you've missed it.
And of course wasn't the point of the "correction".

What _was_ the point of it, I wonder.
Seriously?

Seriously. Why _did_ you post your reply? Just to say "globals are best
avoided"?
[...]
I would prefer the tone of the discussion to stay (become?) friendly or
at least polite :)

Another one with a chip on his shoulder... Sigh...
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top