static variable followed by extern in the same file - c++

The following piece of code compiles as well as executes fine.
What exactly does the extern int a statement mean after static int a.
Note that If i write static int a after extern int a, the compiler throws error as tests.cpp:6: error: a was declared extern and later static
#include<iostream>
//#include "testh.h"
using namespace std;
static int a;
extern int a;
int main()
{
int a;
a=3;
cout<<a<<endl;
cout<<::a<<endl;
return 0;
}

You can declare a variable static then extern, but not extern then static. The result is that the global a still has internal linkage. There is a very similar example (using b as the variable name) in the language standard doc, section [dcl.stc], that states this.

Related

C++ extern variable why can't I define it in main

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.

Using extern array in class method -> undefined reference

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.

Using C-defined structures in C++ code

I'm trying to use C-sourced functions in my C++ code. And I have some difficulties, when I try to instantiate in my C++ code structure which is declared in C-header, and then transfer it to C-function by value. Example:
dummyc.h:
#ifndef _DUMMY_C_H_
#define _DUMMY_C_H_
typedef struct {
int a;
int b;
int c;
int d;
}DUMMYS;
int dummyFunction(unsigned int a, unsigned int b, unsigned short c, DUMMYS dummy);
#endif
dummyc.c:
#include "dummyc.h"
int dummyFunction(unsigned int a, unsigned int b, unsigned short c, DUMMYS dummy){
return 1;
}
dummycpp.cpp:
extern "C"{
#include "dummyc.h"
}
int main(){
DUMMYS s = {0,0,0,0};
return dummyFunction(50,50,1,s);
}
During dummyFunction execution I see that data on stack is incorrect. It seems like they where shifted?? How I can do this correctly??? Im using GCC 4.3.4 for ARM.
The 'extern "C"' directive really only matters for the function declarations. This is because C++ has function overloading. I've always embedded the directive around the function signatures in my header files, using '#ifdef __cplusplus'.
#ifndef _DUMMY_C_H_
#define _DUMMY_C_H_
typedef struct {
int a;
int b;
int c;
int d;
}DUMMYS;
#ifdef __cplusplus
extern "C" {
#endif
int dummyFunction(unsigned int a, unsigned int b, unsigned short c, DUMMYS dummy);
#ifdef __cplusplus
}
#endif
#endif
There's no difference in how C and C++ puts members into structs (when the struct is entirely composed of things that are legal in both C and C++).
When you make this change in dummyc.h, you can remove the 'extern "C"' around the #include directive in dummycpp.cpp.

Invalid use of qualified name

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.

How to declare a global variable that could be used in the entire program

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;