473,385 Members | 1,707 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

best practice for global variables?

Hello,

I'm trying to make sure I use best practices (and hence save myself some
headaches) with the declaration and definition of global variables. Let's
say I have an app with 30 files, including main.cpp I have global
variables that need defining in main.cpp and declaring in all other files
in. The way I've seen it done is to define/declare everything in one header
file (e.g. globalincludes.h) prefaced with the word EXTERN

Then in main.cpp EXTERN is
#define EXTERN

and in all other files EXTERN is
#define EXTERN extern

so everything is extern except in main. However, it still seems like I need
both a definition and declaration. If (in globalincludes.h) I have variable

EXTERN int MonthEndDate[] = {31, 28, 31, 30, 31, 30, 31, 31, 30 ,31, 30,
31};

This works as the definition, but I get multiple redefinitions even with the
extern keyword. Do I need separate declarations too?

extern int MonthEndDate[];

What should my globalincludes.h file look like for this one variable?

Thanks!

Jay

Mar 30 '06 #1
10 6985
* Jay Wolfe:

I'm trying to make sure I use best practices (and hence save myself some
headaches) with the declaration and definition of global variables.
The best practice is: don't use global variables.
[snip] What should my globalincludes.h file look like for this one variable?


The best practice is: don't use global include files.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Mar 30 '06 #2

"Alf P. Steinbach" <al***@start.no> wrote in message
news:49************@individual.net...
* Jay Wolfe:

I'm trying to make sure I use best practices (and hence save myself some
headaches) with the declaration and definition of global variables.


The best practice is: don't use global variables.

[snip]
What should my globalincludes.h file look like for this one variable?


The best practice is: don't use global include files.


Thanks, but that's not really very helpful. All you've done is tell me I
can't do something, but offered no explanation why and no alternatives.
Best practice means what is best to do, not all the things you shouldn't do.
I have common data that every file needs to see and global variables seems
like it was made for this. If you have a good solution, please let me know.

Jay
Mar 30 '06 #3

Jay Wolfe wrote:
"Alf P. Steinbach" <al***@start.no> wrote in message
news:49************@individual.net...
* Jay Wolfe:

I'm trying to make sure I use best practices (and hence save myself some
headaches) with the declaration and definition of global variables.


The best practice is: don't use global variables.

[snip]
What should my globalincludes.h file look like for this one variable?


The best practice is: don't use global include files.


Thanks, but that's not really very helpful. All you've done is tell me I
can't do something, but offered no explanation why and no alternatives.
Best practice means what is best to do, not all the things you shouldn't do.
I have common data that every file needs to see and global variables seems
like it was made for this. If you have a good solution, please let me know.


There is always a way to avoid global variables. One such way is a
singleton.

globals like so:

header.h:

extern type var[];

main.cpp
type var[];

Mar 30 '06 #4
Jay Wolfe posted:
Hello,

I'm trying to make sure I use best practices (and hence save myself
some headaches) with the declaration and definition of global
variables. Let's say I have an app with 30 files, including main.cpp
I have global variables that need defining in main.cpp and declaring
in all other files in. The way I've seen it done is to define/declare
everything in one header file (e.g. globalincludes.h) prefaced with
the word EXTERN

Then in main.cpp EXTERN is
#define EXTERN

and in all other files EXTERN is
#define EXTERN extern

so everything is extern except in main. However, it still seems like I
need both a definition and declaration. If (in globalincludes.h) I have
variable

EXTERN int MonthEndDate[] = {31, 28, 31, 30, 31, 30, 31, 31, 30 ,31,
30, 31};

This works as the definition, but I get multiple redefinitions even
with the extern keyword. Do I need separate declarations too?


The default is "extern", so everything is still "extern" even if you leave
the keyword out. Think of how (at function scope):

int a;

is the same as:

int auto a;

Well, as a global variable, it doesn't matter whether you put in "extern" or
not (when dealing with non-const objects). If a global object is const, then
the default changes to "static".

There' two common ways of accomplishing what you want. Firstly, by just
using a header file:

// global_objects.hpp

static int const month_last_day[] = {31, 28, 31, 30, 31, 30, 31, 31, 30 ,31,
30, 31};

There's no need to write "static" above, as it's the default for global
const variables. The downside to this choice is that you have more than one
object called "month_last_day" -- you've got one object for each translation
unit in which it's declared.

Here's the other way, you use a header file and a source file:

//global_objects.hpp

extern int const month_last_day[12];
//global_objects.cpp

extern int const month_last_day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30
,31, 30, 31};
Now you've only got one object for the entire program.
-Tomás
Mar 30 '06 #5
Jay Wolfe wrote:
Thanks, but that's not really very helpful.
Many people here had to work with legacy codebases that abused globals in
ways that caused and hid bugs. The best tip for them is always "just
don't", so we tend to be a little short. However in your case...
EXTERN int MonthEndDate[] = {31, 28, 31, 30, 31, 30, 31, 31, 30 ,31, 30,
31};


That is a C trick. Because C++ knows that global _constants_ are mostly
harmless, C++ builds the trick into the language - for constants. You can
put this in a header:

static int const MonthEndDate[] = {31, 28, 31, 30, 31, 30, 31, 31, 30 ,31,
30, 31};

Now consider leap years, the precession of the equinoxes, etc. MonthEndDate
isn't _reaaaaally_ constant, so you ought to simply make it a function.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Mar 30 '06 #6

"Tomás" <NU**@NULL.NULL> wrote in message
news:th******************@news.indigo.ie...

Here's the other way, you use a header file and a source file:

//global_objects.hpp

extern int const month_last_day[12];

//global_objects.cpp

extern int const month_last_day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30
,31, 30, 31};


Thank you gentlement for your help, It's getting clearer.

In going back to my original question, it seems you do have 2 elements for
each variable: (1) a declaration included in the header file for inclusion
in all files, and (2) the actual definition in a separate cpp file. The
real difference between what I had and what you present here lies with the
use of the word extern.

Naturally I'd like to avoid multiple instances of global constants, so your
second method seems superior, but why, in global_objects.cpp do you again
use 'extern'?

Thanks!
Jay


Mar 30 '06 #7
Jay Wolfe wrote:
In going back to my original question, it seems you do have 2 elements for
each variable: (1) a declaration included in the header file for inclusion
in all files, and (2) the actual definition in a separate cpp file.Â*Â*The
real difference between what I had and what you present here lies with the
use of the word extern.


Please use 'static' in this specific situation. 'static const' generally
means you may define something in only one .h file, and the compiler will
work out all the details. No extern.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Mar 30 '06 #8
Naturally I'd like to avoid multiple instances of global constants, so
your second method seems superior, but why, in global_objects.cpp do
you again use 'extern'?


I didn't have to, it will still compile if you take it out.

However, the "extern" in the header file is indeed necessary. (I don't know
why... but if I really cared I'd look it up. All I know is that it won't
compile without it.)

Yes, you say that my second way seems superior, but there are times when it
isn't:

// global.hpp

int const monkey = 5;
If you include this in five translation units, then the value can instantly
be subsituted into the code. (So your compiler can turn:

i += monkey;

into:

i += 5;

Which is a good thing!
So basically, use the first method if you have a complicated object, like an
array or a class. Also, any other time when you only want ONE of the object.

Use the second method if you have a simple object, like an "int". Note
however, that in the code I wrote just above, that there's a separate
"monkey" for each translation unit, so you can't use it for something like a
template parameter, as in:

template<int const &n> int Func();

int main()
{
Func<monkey>();
}
To achieve the above behaviour, you need to use the source file/header file
combo.

-Tomás

Mar 30 '06 #9
This is how I'd implement a global array:
// file globalincludes.h

#ifdef DEFINE_GLOBALS
#define EXTERN
#else
#define EXTERN extern
#endif

EXTERN int MonthEndDate[]
#ifdef DEFINE_GLOBALS
= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
#endif
;
// file global.cpp defines the global

#define DEFINE_GLOBALS
#include "globalincludes.h"
// file main.cpp sees only the declaration

#include <iostream>
#include <ostream>
#include "globalincludes.h"

int main() {
std::cout << "month lengths:\n";
for (int i = 0; i < 12; ++i)
std::cout << MonthEndDate[i] << '\n';
return 0;
}
The solution is inelegant, but it does keep the stuff related to that
variable in one place, and is easily comprehensible to other
programmers. It would be nice to avoid that clumsy business of framing
the initializer with preprocessor directives, but I've never figured
out how.

--
Paul Hirose <jv********@earINVALIDthlink.net>
To reply by email remove INVALID

Apr 1 '06 #10
Paul Hirose wrote:
EXTERN int MonthEndDate[]
#ifdef DEFINE_GLOBALS
= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
#endif
;


In C.

C++ can just make the line static and constant, and the compiler will take
care of all that for you.

--
Phlip
http://www.greencheese.org/ZeekLand <-- NOT a blog!!!
Apr 1 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: mark4asp | last post by:
What are the best methods for using global constants and variables? I've noticed that many people put all global constants in a file and include that file on every page. This is the best way of...
9
by: Mark Twombley | last post by:
Hi, I'm just getting back into C++ and had a question about the best practice for assigning error numbers. I have been working in VB for sometime now and there you would start assigning error...
18
by: vib | last post by:
Hi there, By chance, I came to learn that it is bad programming practice to initialize global variables at outside of programs. Is it that bad? In order to fullfil this, I had to declare them...
5
by: Fred Nelson | last post by:
Hi: I'm a relative newby so hopefully this is a simple question! I have found that I can create global variables easily on a web page by placing the dim statement before the first "private...
17
by: Woody Splawn | last post by:
I am finding that time after time I have instances where I need to access information in a variable that is public. At the same time, the books I read say that one should not use public variables...
8
by: newbie | last post by:
Hello, I have questions about global variables in OOP (in general) and Python (in specific). I understand (I think) that global variables are generally not a good idea. However, if there are...
4
by: Marc E | last post by:
All, I'm coming from java and coldfusion, where one can set a "global" variable in one place (the servletcontext in java, Application.cfm in coldfusion) and all files in that site can then take...
1
weaknessforcats
by: weaknessforcats | last post by:
C++: The Case Against Global Variables Summary This article explores the negative ramifications of using global variables. The use of global variables is such a problem that C++ architects have...
1
by: danep2 | last post by:
Let me start by saying that this is more a question about principle than practice - with the speed of today's computers it's probably rarely an actual issue. Still I'd like to know... If I have...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.