C++ What should I do instead of global variables? [duplicate] - c++

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
C++: Easiest way to access main variable from function?
I need to get my variable "input" from my main function in a.cpp to another function named check in b.cpp. I looked into it on Google and this forum/thingy, and I found you could do it with global variables using extern, but that's it's also bad to use those and I couldn't find an answer to what an alternative is? How should I transfer the data in the variable to the other function without using globals?
Code of how I got arguments to work.
(What I'm trying to do here is a console "manager" for solutions of project Euler which I can call to solve/view via input, I started working on the code 40 mins ago.)
main.cpp
#include <iostream>
#include <windows.h>
#include "prob.h"
using namespace std;
int check(string x);
int main()
{
string input = "empty";
clear();
cout << "Welcome to the Apeture Labs Project Euler Console! (ALPEC)" << endl << endl;
cout << "We remind you that ALPEC will never threaten to stab you" << endl;
cout << "and, in fact, cannot speak. In the event that ALPEC does speak, " << endl;
cout << "we urge you to disregard its advice." << endl << endl;
cin >> input;
cin.get();
check(input);
cout << input << endl;
cin.get();
return 0;
}
prob.h
#ifndef PROB_H_INCLUDED
#define PROB_H_INCLUDED
int main();
int clear();
int check();
int back();
int P1();
int P2();
int P3();
int P4();
#endif // PROB_H_INCLUDED
back.cpp
#include <iostream>
#include <windows.h>
#include "prob.h"
using namespace std;
int clear()
{
system( "#echo off" );
system( "color 09" );
system( "cls" );
return 0;
}
int check( string x )
{
if( x == "help" );
if( x == "empty" )
{
cout << "And.... You didn't enter anything..." << endl << endl;
}
else
{
cout << "Do you have any clue what you are doing? " << endl << endl;
}
return 0;
}

By passing the data as an function argument.
For example:
int doSomething(int passedVar)
{
}
int main()
{
int i = 10;
doSomething(i);
return 0;
}
Note that the function definition may reside even in a different cpp file. The main only needs to see the function declaration, and the linker shall link the function definition correctly.
Usually, one would add the function declaration in a header file and include the header file in main, while providing the function definition in another cpp file.
The code you show has number of problems:
You do not need to declare main in the header file.
Your function declaration and definition of check() do not match. Your header file says it takes no argument and you define a the function definition to take one argument. Obviously, they don't match. As they stand now they are two completely different functions.
As the compiler sees it you declared one function who's definition you never provided and you defined another function in the cpp file. Thus the function declared(one with no parameters) was never defined and hence the definition not found error.

Andrei Tita is absolutely correct. If you have a "value" in one module (e.g. "main()" in a.cpp), and you wish to use that value in a function (e.g. "foo()" in b.cpp) ... then just pass that value as a function argument!
As your programs become more sophisticated, you'll probably start using classes (instead of functions) .

Related

Calling functions while using multiple .cpp files

I would like to ask a question about the output when I called an inline function, that was declared inside MyHeader.h, which was defined in both source_1.cpp and source_2.cpp files, using the int main() function inside source_2.cppfile.
When I do such a call, the one defined inside the source_1.cpp function is called. The codes are like;
My MyHeader.h contains the following line of codes:
#pragma once
#include <iostream>
inline int func(void);
My source_1.cpp contains the following line of codes:
#include "MyHeader.h"
int func(void)
{
std::cout << "func(), inside source_1, was called. 102 * 102 will be returned." << "\n";
return 102 * 102;
}
void source_1(void)
{
std::cout << "source_1() was called. func() will be called." << "\n";
func();
}
My source_2.cpp contains the following line of codes:
#include "MyHeader.h"
int func(void)
{
std::cout << "func(), inside source_2, was called. 102 * 102 will be returned." << "\n";
return 102 * 102;
}
void source_2(void)
{
std::cout << "source_2() was called. func() will be called." << "\n";
func();
}
int main()
{
std::cout << "main() was called." << "\n";
source_2();
}
This is the output:
main() was called.
source_2() was called. func() will be called.
func(), inside source_1, was called. 102*102 will be returned.
I wish to know the reason.
You violated the one definition rule. You are not permitted to have non-static objects in your program with different implementations. The compiler/linker is free to choose any implementation it finds, which can lead to very hard to find bugs.
Your source_2 function called func function of source_1.cpp because func is declared as inline , not static . When the linker gets a inline function, it remove all copies of that function except one. So the func function of source_1.cpp is kept, other one is removed by the linker. If you want to have two separate implementation of one function in two source file, declare the function as static . This prevents the linker from removing multiple functions of same name.

inline overload throwing errors c++

I am learning overloading an inline function.
In testing this code I can't compile with the following errors I can't understand as to what's wrong.
I tested it with only 1 inline function and works but a second breaks it. Can you please share some guidance:
Thank you for your help, Sergio
Compiler errors:
abs exception specification does not match previous declaration line 13
function long abs (const long) throw() already has body line 13
abs redefinition; different exception specification line 19
abs error in function definition or declaration; function not called line 30
abs error in function definition or declaration; function not called line 32
#include "pch.h"
#include <iostream>
using namespace std;
// Overload abs() three ways
inline int abs(int n)
{
cout << "In integer abs() \n";
return((n < 0) ? -n : n);
}
inline long abs(long n)
{
cout << "In long abs() \n";
return((n < 0) ? -n : n);
}
inline double abs(double n) {
cout << "In double abs() \n";
return ((n < 0 ? -n : n));
}
int main()
{
cout << "Absolute value of -10 Is ";
cout << abs(-10) << "\n";
cout << "Absolute value of -10L Is ";
cout << abs(-10L) << "\n";
cout << "Absolute value of -10.01 Is ";
cout << abs(-10.01) << "\n";
}
Your error is here:
using namespace std;
since this brings into the global namespace the definitions of the function overloads std::abs() (they are declared & defined in cmath which appears to be #included directly or indirectly into iostream), which then clash with your own definitions. The above statement (using namespace std;) is almost never a good idea, certainly not in a header file -- it is, unfortunately, commonly used in online coding contests to simplify code (no need for std::).
Btw, this has only do with inline inasmuch as the function definitions (not the declarations) clash, which must be declared inline in header files to obtain the proper linkage.
Precense of using namespace std; causes a conflict with ::std::abs function. However getting rid of using namespace std; will not solve the issue complitely.
The primary problem here is the use of a non-unique name for a function in global namespace. abs is a function from C standard library therefore you should not use this name for your own functions. Otherwise your may get an error if <stdlib.h> is included somewhere, or even a random Undefined Behavior because of ODR violation.
In order to prevent name conflicts in C++ you should typically define new functions in custom namespace:
n_sergio_solorzano_stuff
{
// Overload abs() three ways
inline int abs(int n)
{
...
or select globally unique names when you need to add something into global namespace:
inline int sergio_solorzano_stuff_abs(int n)

How to make a variable available to multiple .cpp files using a class?

This question has derived from this one.
I have a working program which must be split into multiple parts. In this program is needed to use a variable (now it's a GTK+ one :P) many times in parts of the program that will end up in separated .cpp files.
So, I made a simple example to understand how to make variables available to the program parts. A modified version of the previous code would be:
#include <iostream>
using namespace std;
int entero = 10;
void function()
{
cout<<entero<<endl;
//action1...;
}
void separated_function()
{
cout<<entero<<endl;
//action2...;
}
int main( int argc, char *argv[] )
{
function();
separated_function();
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}
It is needed to split the code correctly, to have function(), another_function() and main() in separated .cpp files,and make entero avaliable to all of them... BUT:
In the previous question #NeilKirk commented:Do not use global variables. Put the required state into a struct or class, and pass it to functions as necessary as a parameter (And I also have found many web pages pointing that is not recommended to use global variables).
And, as far I can understand, in the answer provided by #PaulH., he is describing how to make variables avaliable by making them global.
This answer was very useful, it worked fine not only with char arrays, but also with ints, strings and GTK+ variables (or pointers to variables :P).
But since this method is not recommended, I would thank anyone who could show what would be the correct way to split the code passing the variables as a function parameter or some other method more recommended than the - working - global variables one.
I researched about parameters and classes, but I'm a newbie, and I messed the code up with no good result.
You need to give the parameter as a reference if you want the same comportement as a global variable
#include <iostream>
using namespace std;
// renamed the parameter to avoid confusion ('entero' is valid though)
void function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value
//action1...;
}
void separated_function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value again
//action2...;
}
int main( int argc, char *argv[] )
{
int entero = 10; // initializing the variable
// give the parameter by reference => the functions will be able to modify its value
function(entero);
separated_function(entero);
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}
output:
10
11
12
Defining a class or struct in a header file is the way to go, then include the header file in all source files that needs the classes or structures. You can also place function prototypes or preprocessor macros in header files if they are needed by multiple source files, as well as variable declarations (e.g. extern int some_int_var;) and namespace declarations.
You will not get multiple definition errors from defining the classes, because classes is a concept for the compiler to handle, classes themselves are never passed on for the linker where multiple definition errors occurs.
Lets take a simple example, with one header file and two source files.
First the header file, e.g. myheader.h:
#ifndef MYHEADER_H
#define MYHEADER_H
// The above is called include guards (https://en.wikipedia.org/wiki/Include_guard)
// and are used to protect the header file from being included
// by the same source file twice
// Define a namespace
namespace foo
{
// Define a class
class my_class
{
public:
my_class(int val)
: value_(val)
{}
int get_value() const
{
return value_;
}
void set_value(const int val)
{
value_ = val;
}
private:
int value_;
};
// Declare a function prototype
void bar(my_class& v);
}
#endif // MYHEADER_H
The above header file defines a namespace foo and in the namespace a class my_class and a function bar.
(The namespace is strictly not necessary for a simple program like this, but for larger projects it becomes more needed.)
Then the first source file, e.g. main.cpp:
#include <iostream>
#include "myheader.h" // Include our own header file
int main()
{
using namespace foo;
my_class my_object(123); // Create an instance of the class
bar(my_object); // Call the function
std::cout << "In main(), value is " << my_object.get_value() << '\n';
// All done
}
And finally the second source file, e.g. bar.cpp:
#include <iostream>
#include "myheader.h"
void foo::bar(foo::my_class& val)
{
std::cout << "In foo::bar(), value is " << val.get_value() << '\n';
val.set_value(456);
}
Put all three files in the same project, and build. You should now get an executable program that outputs
In foo::bar(), value is 123
In main(), value is 456
I prefer to provide a functional interface to global data.
.h file:
extern int get_entero();
extern void set_entero(int v);
.cpp file:
static int entero = 10;
int get_entero()
{
return entero;
}
void set_entero(int v)
{
entero = v;
}
Then, everywhere else, use those functions.
#include "the_h_file"
void function()
{
cout << get_entero() << endl;
//action1...;
}
void separated_function()
{
cout << get_entero() << endl;
//action2...;
}
int main( int argc, char *argv[] )
{
function();
separated_function();
cout<< get_entero() <<endl;
//something else with the mentioned variables...;
return 0;
}
If you do not plan to modify the variable, it is generally ok to make it global. However, it is best to declare it with the const keyword to signal the compiler that it should not be modified, like so:
const int ENTERO = 10;
If you are using multiple cpp files, also consider using a header file for your structures and function declarations.
If you are planning on modifying the variable, just pass it around in function parameters.

Calling External Codes

Is it possible to call routines from an external file like notepad (or also cpp file if needed)?
e.g.
I have 3 files.
MainCode.cpp
SubCode_A.cpp <- not included in the headers of the MainCode.cpp
SubCode_B.cpp <- not included in the headers of the MainCode.cpp
MainCode_A.cpp
#include <iostream>
using namespace std;
int main ()
{
int choice = 0;
cin >> choice;
if (choice == 1)
{
"call routines from SubCode_A.cpp;" <- is there a possible code for this?
}
else if (choice == 2)
{
"call routines from SubCode_B.cpp;" <- is there a possible code for this?
}
return 0;
}
=================================
SubCode_A.cpp CODES
{
if (1) //i need to include if statement :)
cout >> "Hello World!!";
}
=================================
SubCode_B.cpp CODES
{
if (1) //i need to include if statement :)
cout >> "World Hello!!";
}
Make the code in e.g. SubCode_A.cpp a function, then declare this function in your main source file and call it. You of course have to build with all source files to create the final executable.
You can just use an #include statement.
Include instructs the compiler to insert the specified file at the #include point.
So your code would be
if (choice == 1)
{
#include "SubCode_A.cpp"
}
...
And you wouldn't need the extra braces in the SubCode_?.cpp files because they exist in MainCode.cpp
Of course, the compiler will only compile what is in the SubCode files at the time of compilation. Any changes to source that aren't compiled won't end up in your executable.
But mid source #includes doesn't lend itself to very readable code.
No
You have to compile both codes,
Declare an external function (e.g. extern void function (int);, in a header.
Compile those two files which will include this header.
Then in a 3rd file, where you use it just include the header.
BUT as you include all the 3 files in the compilation it will work.
This other post maybe useful : Effects of the extern keyword on C functions
It is not possible to call the code in another executable. It is possible for one application to expose an "api" (application programming interface) through a library or DLL which allows you to call some of the code that the application uses.
While compiling YOUR code, though, the compiler needs to know the "fingerprint" of the functions you are going to call: that is, what it returns and what arguments it takes.
This is done through a declaration or "prototype stub":
// subcode.h
void subCodeFunction1(); // prototype stub
void subCodeFunction3(int i, int j);
// subcode.cpp
#include <iostream>
void subCodeFunction1()
{
std::cout << "subCodeFunction1" << std::endl;
}
void subCodeFunction2()
{
std::cout << "subCodeFunction2" << std::endl;
}
void subCodeFunction3(int i, int j)
{
std::cout << "subCodeFunction1(" << i << "," << j << ")" << std::endl;
}
// main.cpp
#include "subcode.h"
int main() {
subCodeFunction1(); // ok
subCodeFunction2(); // error: not in subcode.h, comment out or add to subcode.h
subCodeFunction3(2, 5); // ok
return 0;
}

C++ callback function run time error

I have a function that accepts function pointer as an argument and calls the function pointer as shown below.
int foo (int a, int(*calc)(int))
{
int y;
// ....
// calling calc function via callback
(*calc)(y);
}
The calc function to be called back looks like
int calc(int x)
{
// ....
cout << x;
checkValue(x);
}
function foo is placed in a.cpp and function calc() and checkValue() are defined in files b.cpp and c.cpp. My problem is calc() executes fine until the cout statement and fails to call checkValue() function. The crash report I received is:
symbol lookup error:..... undefined symbol: _ZNSaIcEC1Ev, version GLIBCXX_3.4
How can I solve this problem?
The symbol _ZNSaIcEC1Ev is the mangled name for the std::allocator<char>::allocator() zero-argument constructor (I determined this using the c++filt(1) program). The error message "symbol lookup error:..... undefined symbol" relates to dynamic linking and has nothing to do with calling a function through a function pointer.
Your error almost certainly lies somewhere else. You're probably getting confused about the location of the error due to stdout buffering -- strings are getting printed to stdout, but you're not seeing them show up because they're getting buffered in memory, and then the program crashes before they're displayed. To avoid that, you need to make sure to flush the output after every print statement (e.g. by inserting std::cout << std::endl or std::cout << std::flush or explicitly calling std::cout.flush()), or by using std::cerr instead of std::cout, which is unbuffered by default.
#include <iostream>
using namespace std;
int calc(int x){
cout<< "calc:" << x << endl;
}
int CALC(int x) {
cout << "CALC: " << x << endl;
}
int foo (int a, int(*callback)(int)){
cout << "Calling calc on:" << a << endl;
(*callback)(a);
}
int main() {
cout << "START" << endl;
foo(5, calc);
foo(6, CALC);
}
This works fine for me.
gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)
Note: I removed your "checkValue(x)" call, the issue could be in there...