Alternatives To Global Variables in C++ - c++

I need to set a variable in the main function and access it from a different function in the same file. I can not pass it to the function because it means changing the entire code structure, which is not an option. To avoid declaring a global variable I crated a namespace and I want to check if this is a good programming practice or is there a cleaner way to do it.
This is the code:
namespace mylocalnamespace{
int myglobalvar;
}
static void myFunc()
{
..... some code
operationX(mylocalnamespace::myglobalvar);
..... some code
}
int main(int argc, char **argv)
{
..... some code
mylocalnamespace::myglobalvar = atoi(argv[0]);
..... some code
}

Alternatives To Global Variables in C++
In the example, function argument is a good alternative to avoid a global variable:
static void myFunc(int mylocalvar)
{
..... some code
operationX(mylocalvar);
..... some code
}
int main(int argc, char **argv)
{
..... some code
mylocalvar = atoi(argv[0]);
..... some code
myFunc(mylocalvar);
}
I can not pass it to the function
Oh well, then you have to use a global variable.
Since you apparently use it in a function with internal linkage, you could improve slightly by using global with internal linkage as well. This way the global won't leak to other translation units. A handy way to achieve that is an anonymous namespace:
namespace {
int myglobalvar;
void myFunc() {
// ...
To avoid declaring a global variable I crated a namespace
Global variables are still global variables even if not in the global namespace.

Related

Qt C++ Create a Global Variable accessible to all classes

Is it possible to create a variable globally accessible to all classes in my program in which if I change it's value from one class it will also change for all other classes?
If so, how do I implement such?
Everyone keeps parroting that "globals are evil", but I say that pretty much everything can be used or misused. Also, if globals were intrinsically bad, they simply wouldn't be allowed in the first place. In the case of globals, there is quite the potential for accidental misuse to very negative consequences, but they are 100% fine if you actually know what you are doing:
// globals.h - for including globals
extern int globalInt; // note the "extern" part
// globals.cpp - implementing the globals
int globalInt = 667;
It may also be a very good idea to use namespaces to avoid naming conflicts and keep the scope cleaner, unless you are particularly meticulous with your naming conventions, which is the olden "C" way to do namespaces.
Also, and especially if you are using multiple threads, it might be a good idea to create an interface for accessing the encapsulated global stuff that will also have modular locks or even be lock-less wherever possible (for example direct use of atomics).
But a global is not necessarily the only solution. Depending on what you actually need, singletons or static class members might do the trick while keeping it a little more tidy and avoiding the use of evil globals.
Such variable have to be defined once somewhere but then used in different compilation units. However, in order to use something, you know, you need to tell the compiler that it exists (declare it). extern keyword lets you declare that something exists somewhere else.
In order to structure your code you can do what xkenshin14x (kind of?) proposed:
global.h
#pragma once
#include <string>
// Declaration
namespace global
{
extern int i;
extern float f;
extern ::std::string s;
}
global.cpp
#include "global.h"
// Definition
namespace global
{
int i = 100;
float f = 20.0f;
::std::string s = "string";
}
main.cpp
#include "global.h"
int main(int argc, char *argv[])
{
std::cout << global::i << " " << global::f << " " << global::s;
return 0;
}
It is good to use a namespace in this case as it lets you to avoid name collisions which are inherent for global variables.
Alternatively, it is possible to encapsulate all global stuff inside a one "global" object. I quoted word "global" because indeed this object is static to a global function so technically no global variables involved :)
Here is a header only implementation:
global.h
#pragma once
class Global
{
public:
int i = 100;
float f = 20.0f;
// and other "global" variable
public:
Global() = default;
Global(const Global&) = delete;
Global(Global&&) = delete;
static Global& Instance()
{
static Global global;
return global;
}
};
namespace {
Global& global = Global::Instance();
}
// static Global& global = Global::Instance(); if you like
test.h
#pragma once
#include "global.h"
struct Test
{
void ChangeGlobal() {
global.i++;
}
};
main.cpp
#include <iostream>
#include "global.h"
#include "test.h"
int main()
{
Test t;
std::cout << global.i << " " << global.f << std::endl;
t.ChangeGlobal();
std::cout << global.i << " " << global.f << std::endl;
return 0;
}
There are at least two benefits in a such approach:
You don't literally use any global objects.
In your Global class you can add variable accessors with mutexes inside where it is needed. For example, void SetSomething(const Something& something) { ... }
If you just use this global variable in UI thread(for QApplication ui app) or main thread(for QCoreApplication console app),it will be convenient to code and you may design a custom data struct.But if you use it in multithread environment,you should need mutex or atomic to protect global variables.
Global variables should be avoided as you probably know.
But you could create a header file for the global variables and #include "globals.h" in each place you want to use it in. Then you can use each variable normally.

Trouble with using namespace and static methods

I am trying to write some namespaces statics methods and variables in order to have a set of functions i can use from anywhere in the code. This is what I have:
Header:
namespace CProfileIO
{
static void setAppDir(std::string appDir);
static int reloadProfiles();
static std::string directory;
static std::list<std::string> profilesList;
}
Source:
namespace CProfileIO
{
void setAppDir(std::string appDir)
{
directory = appDir;
}
int reloadProfiles()
{
// ...
}
} // namespace CProfileIO
Then somewhere in the code I have:
#include "CProfileIO.h"
int main(int argc, char * argv[])
{
string appDir = string(dirname(*argv));
CProfileIO::setAppDir(appDir);
.
.
.
}
When I try to compile, i get error at the line I am using the function:
... undefined reference to `CProfileIO::setAppDir(std::string)'
I cant figure out what is wrong. I would aprichiate all help!
You should not use static functions here, as they are visible only in the current translation unit. Thus, you declare a static function which you define (statically) in the cpp, then it won't be visible from other translation units.
You should simply not use the static keyword here, but declare variables (but not functions) as extern.
Also, I recommend to pass the string argument as const reference (void setAppDir(const std::string& appDir);)
That is because static methods are only visible in the current module, (source file). They are not linked.
Hence you other sourcefile doesn't find the function. That is supposed to happen if you use static. I don't know why you would declared naked functions as static, maybe you meant to put them into a class?

c static method calls with friendly method name

I have a header file helper.h
class helper
{
public:
static int someVal();
};
int helper::someVal()
{
return 999;
}
In my c class I call the someVal method as follows
#include "helper.h"
.
.
int answer = helper::someVal();
Is there way to have a call like this instead?
int answer = someVal();
Solution from below is
helper.h --
static int someVal();
int someVal()
{
return 999;
}
Not exactly, but you can make helper a namespace instead of a class:
namespace helper
{
static int someVal();
}
using namespace helper;
int answer = someVal();
You can define the function just as you did in the question. In practice is's often better to not use using namespace for your own functions because that makes it easier to understand which function is called.
If you only have a class with static functions, you could use a namespace with functions instead. You could later use using namespace to access the function without the namespace name.
why should you want to? someone reading the code (even yourself in near future) is very happ not to misinterpret the function as global. when you do good naming on class and member function you would miss important information without class name. Factory::get_instance() carries more information than get_instance().

declaration syntax error

What's wrong with this one? The compiler says: Declaration syntax error.
Source File:
#include<iostream>
using namespace std;
int main(int argc, char **argv) {
void printBinary(const unsigned char val) {
//printBinary() func. outputs byte in binary
for(int i=7;i>=0;i--)
if(val & (1<<i)) //generates a single bit with offset position
std::cout<<"1";
else
std::cout<<"0"
}
return 0;
}///:~
Header file:
void printBinary(const unsigned char val);
///:~
You are trying to define one function inside another function. This is illegal. Why did you place the definition of printBinary into the body of main?
Aside from the lambda functions in C++11, C++ has no such feature as local functions. All functions "live" in namespace scope.
The only workaround for this rule is inline member function definitions for local classes, although it does not produce a local function either.
You can't define a function in another function's (in this case, main) body.
//EDIT: Unless, of course, it's lambda.

VC++: non-global old-style function declarations?

In Visual Studio 2003 using pure C, old-style function
declarations do not show as global member
i.e. void func(blah) int blah;{...}
This shows as a global member in the members dropdown:
void func(int blah)
{
...
}
This compiles, but old-style does not appear in the global
members dropdown:
void func(blah)
int blah;
{
...
}
I am trying to use the new 'Calling Graph' functionality to
analyse code, but as most of our legacy code uses the
old-style function parameters, those functions are not
recognized are not shown as Global Members, and therefore do
not appear in the 'Calling Graph'.
Is there any way to let the "call graph" analysis process
old-style function declarations correctly?
Maybe you want to consider to just change the old style function signatures. There shouldn't be any issues with that.
EDIT:
For an automatic conversion of your source files from old style syntax to ANSI-C style, take a look at the cproto tool. Maybe that could save you some time if you decide to go that direction.
This is an excerpt from the docs:
-f n
Set the style of generated function prototypes where n is a
number from 0 to 3. For example,
consider the function definition
main (argc, argv)
int argc;
char *argv[];
{
}
If the value is 0, then no prototypes are generated. When set to
1, the output is:
int main(/*int argc, char *argv[]*/);
For a value of 2, the output has the form:
int main(int /*argc*/, char */*argv*/[]);
The default value is 3. It produces the full function prototype:
int main(int argc, char *argv[]);
I'm not sure but maybe the engine uses regexs to trace routine signatures and the old C style isn't implemented.