Can someone please explain me why
#include <iostream>
namespace helper1 {
void syncAPI();
};
void helper1::syncAPI() {
extern int *arrayOfIntPointers[];
std::cout << *arrayOfIntPointers[0] << std::endl;
}
int *arrayOfIntPointers[5];
int main()
{
int *newInt = new int;
*newInt = 1;
helper1::syncAPI();
}
results in this error
In function `helper1::syncAPI()': undefined reference to helper1::arrayOfIntPointers
instead of displaying '1'?
And why seems arrayOfIntPointers to be a member of helper1 ( helper1:: arrayOfIntPointers)?
EDIT: I want to access the global array from within the function syncAPI() because all necessary data will be stored there.
The declaration extern int *arrayOfIntPointers[]; is still inside the namespace, even though it's an extern declaration. So it declares helper1::arrayOfIntPointers.
The definition int *arrayOfIntPointers[5]; is outside a namespace, so it defines
arrayOfIntPointers in the "global" namespace - a different object.
To fix this, the extern declaration and the definition must match. Either define your arrayOfIntPointers inside your namespace or declare it outside the namespace. So you have two solutions:
Outside (preferred)
extern int *arrayOfIntPointers[];
void helper1::syncAPI()
{
...
}
Inside
namespace helper1
{
int *arrayOfIntPointers[5];
}
Because arrayOfIntPointers is not a member of namespace helper1 and the extern declaration within the function is most likely not what you want.
Related
use.cpp
#include "my.h"
int main()
{
int foo = 7;
print_foo();
print(99);
}
my.h
#pragma once
extern int foo;
void print_foo();
void print(int i);
my.cpp
#include<iostream>
#include "my.h"
void print_foo()
{
std::cout << foo;
}
void print(int i)
{
std::cout << i;
}
So my question is pretty simple I declare an extern int foo in the header file then I DEFINE foo in main, why does this not work? If I don't define foo in main and define it outside of main in use.cpp then it works but when I define it in main() it doesn't. Why?
At global scope, the declaration
extern int foo;
declares a variable named foo that has external linkage, meaning that it might be defined in another translation unit.
At block scope (i.e., as a statement in the body of a function), the definition
int foo = 7;
has no linkage. That means that the compiler will never consider this foo to be the same entity as another foo from another scope. Therefore, this simply creates another variable that's unrelated to the global one, and does not initialize the global one.
everyone! there is a code snippet like the below:
testcase.cpp
#include <string>
#include <iostream>
using namespace std;
class Test {
public:
static int b ;
static void test()
{
b = 3;
cout << b<<endl;
}
};
int main()
{
Test::test();
return 0;
}
when I click "build" button,the output message is
error LNK2001: unresolved external symbol "public: static int Test::b" (?b#Test##2HA)
1>B:\PROGRAMPROJECT\visual 2015 pro\testcase\testcase\x64\Debug\testcase.exe : fatal error LNK1120: 1 unresolved externals
but,when i change the code location like this:
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
class Test {
public:
//static int b;
static void test()
{
static int b;//only change this line
b = 3;
cout << b << endl;
}
};
int main()
{
Test::test();
return 0;
}
It does work!
I don't know why?Anybody can help me?
My IDE is vs pro 2015 + windows10.
How to solve it
Using C++17 you can inline the static variable which removes the need to define it outside the class.
static inline int i = 0; // I would also initialize it to zero, just to be sure
If you cannot use C++17 you will have to define
int Test::b = 0; // Again I would also initialize it to zero, just to be sure
outside of class Test
To the why
When you wrote
static void test()
{
static int b; // <-- definition is here
b = 3;
cout << b << endl;
}
you defined the function directly in the class (which means it is automatically marked inline). You then also have the definition of your static variable right there. If it is outside of the function scope, it is only a declaration (except if explicitly marked as inline - as shown above).
In contrast, in the other case it is outside of the function definition and hence your are missing the definition of the static variable.
class Test {
public:
static int b ; // <-- only declaration - definition is missing
static void test()
{
b = 3;
cout << b<<endl;
}
};
Fix spelled out for C++17
class Test {
public:
static inline int b = 0; // <-- now it is defined (and for safety initialized)
static void test()
{
b = 3;
cout << b<<endl;
}
};
Fix spelled out prior to C++17
#include <string>
#include <iostream>
using namespace std;
class Test {
public:
static int b; // declaration
static void test()
{
b = 3;
cout << b << endl;
}
};
int Test::b = 0; // definition
int main()
{
Test::test();
return 0;
}
The other anwers focus on solving the problem, instead of answering the "why" part.
When you define a function within class body, it is automatically considered to be inline and any number of translation units (think about C++ sources) may define them. That's the way you would normally define functions within header file - a function that's body will be included in multiple sources.
When you only declare a function within class body, but define it outside, it is not automatically marked as inline, which means that each translation unit that contains this definition will generate its own strong symbol. In this case, you usually decouple the declaration in a header file, from implementation in an associated source file, otherwise you'd get multiple symbol errors. (i.e. if you have non-inline definitions in headers, each source that include them generates those symbols and linker gets confused because it sees multiple versions of the same non-inline function coming from different sources)
Now, when you define a static member variable, unless it's inline, it also must be also associated with a translation unit. It's similar to declaring an extern global variable, that also has to be defined somewhere. In your case, you should simply add:
int Test::b;
It's more important when you decouple definition from declaration. Say, you have two files:
Test.hpp
class Test {
public:
static int b ;
static void test();
};
Test.cpp
#include "Test.hpp"
int Test::b;
void Test::test()
{
b = 3;
cout << b<<endl;
}
The symbols (in this case, the global variable Test::b and the function Test::test) are associated with the file Test.cpp and are generated exactly once. You may include Test.hpp in any number of source files and no additional symbols will be generated.
For referece, see https://en.cppreference.com/w/cpp/language/static
You've declared Test::b but you haven't defined it. Add this line to your code (outside of the Test class)
int Test::b;
you can give an initial value as well if you wish
int Test::b = 123;
In C, If we re-declare variable inside enum, then compiler gives an error that "'i' redeclared as different kind of symbol".It Ok.
#include <stdio.h>
int i = 10;
struct S
{
enum
{
i = 20
}e;
};
int main()
{
printf("%d\n", i);
}
But, In C++, If we redeclare variable inside enum, then it's working fine.
#include <iostream>
using namespace std;
int i = 10;
struct S
{
enum
{
i = 20
}e;
};
int main()
{
cout<<i<<endl;
}
I don't understand, Why doesn't C++ compiler gives an error for redeclaration variable?
It doesn't give a re-declaration error because the enumerator is introduced into class scope. Recall that a struct and class are mostly interchangeable in C++. The scope of S contains the enumerator i.
In C however, struct S doesn't define a scope. There are only 4 types of scope in C: function, file, block, and function prototype. As such, i is introduced into file scope where the variable i is already defined.
I'm trying the following:
#include <iostream>
namespace A
{
extern int j;
}
int main()
{
int A::j=5;
std::cout << A::j;
}
But I've error: invalid use of qualified-name ‘A::j’. Please explain why this error occurred?
Please explain why this error occurred?
The language simply doesn't allow you to define namespace-scope variables inside functions. The definition has to be either in namespace A:
namespace A {
int j = 5;
}
or in the surrounding (global) namespace:
int A::j = 5;
You can, of course, assign a value to the variable inside the function:
int main() {
A::j = 5;
// ...
}
but you'll also need a definition somewhere, since your program doesn't have one.
#include <iostream>
namespace A
{
int j;
}
int main()
{
A::j=5;
std::cout << A::j;
return 0;
}
Since you declare j in namespace A as extern in the global area, you also need its definition. But in main, you try to assign to it, which also need the symbol definition when linking. So you can remove the extern in namespace A, and remove the 'int' keyword when assigning.
I have a variable that I would like to use in all my classes without needing to pass it to the class constructor every time I would like to use it. How would I accomplish this in C++?
Thanks.
global.h
extern int myVar;
global.cpp
#include "global.h"
int myVar = 0; // initialize
class1.cpp
#include "global.h"
...
class2.cpp
#include "global.h"
...
class3.cpp
#include "global.h"
...
MyVar will be known and usable in every module as a global variable. You do not have to have global.cpp. You could initialize myVar in any of the class .cpp's but I think this is cleaner for larger programs.
While I would like to avoid global variables like the plague as our software cannot be multithreaded effectively due to the high reliance on global variables, I do have some suggestions:
Use a Singleton. It will allow you to keep the code and access clean. Part of the problem with a global variable is you don't know what code has modified it. You could set the value of global somewhere in your function relying on the hope that no one else will change it, but function your code calls, fooA, changes it and now your code is a) broken, and b) hard to debug.
If you have to use a global variable without touching the singleton pattern, look at fupsduck's response.
If you're not going to use the Singleton pattern as Lyndsey suggests, then at least use a global function (inside a namespace) to access the variable. This will give you more flexibily in how you manage that global entity.
// mymodule.h
namespace mynamespace // prevents polluting the global namespace
{
extern int getGlobalVariable();
}
// mymodule.cpp
namespace mynamespace
{
int myGlobalVariable = 42;
int getGlobalVariable()
{
return myGlobalVariable;
}
}
Just declare it outside the class:
Header file:
extern int x;
class A {
int z;
public:
A() : z(x++) {}
};
One source file:
int x = 0;
keyword extern
//file1.cpp
int x = 0;
//file1 continues and ends.
//file2.cpp
extern int x; //this gets tied into file1.cpp's x at link time.
//file2.cpp goes on and ends
Declare the variable as extern in a common header.
Define it in any source file.
// L.hpp
struct L { static int a; };
// L.cpp
int L::a(0);
The below solution should be simple enough as per the title "How to declare a global variable that could be used in the entire program
" .
If you want to use it in a different file then make use of extern keyword.
Please let me know if there is any issue with the solution
#include<iostream>
using namespace std;
int global = 5;
class base {
public:
int a;
float b;
base (int x) {
a = global;
cout << "base class value =" << a << endl;
}
};
class derived : public base {
public:
int c;
float d;
derived (float x, int y) : base (y)
{
d = global;
cout << "derived class value =" << d << endl;
}
};
int main ()
{
derived d(0,0);
cout << "main finished" << endl;
return 0;
}
if you want to declare it in different header files/cpp files, just declare it extern outside of other files
//file1.c
int x=1;
int f(){}
//file2.c
extern int x;