Redeclare variable inside enum - c++

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.

Related

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.

Variable declaration in C++ within namespaces

In a library I am working with some variables are declared like that:
char &ns::x = y;
However, if I do it that way I get the following error:
error: no member named 'x' in namespace 'ns'
If I rewrite it, it works:
namespace ns {
char &x = y;
}
What exactly is the difference? And why is it working within the library?
If you’re right and the code from the library is exactly as written, then this implies that elsewhere in this library, you’ll find the following declaration:
namespace ns {
extern char& x;
}
In other words, x must have already been declared (and not defined!) inside ns.
The first declaration
char &ns::x = y;
assumes that the name x is already declared in the namespace ns. However this assumption is wrong (in the provided code snippet there is no previous declaration of the variable. Possibly the code snippet is not complete.).
The code snippet can works provided that the variable x is already declared (without its definition) in the namespace ns.
For example
#include <iostream>
namespace ns
{
extern char &x;
}
char y;
char & ns::x = y;
int main() {
return 0;
}
In this code snippet
namespace ns {
char &x = y;
}
there is defined a reference that is initialized by the object y.
The Variable declaration using namespace:
#include <iostream>
using namespace std;
// Variable created inside namespace
namespace first
{
int val = 500;
}
// Global variable
int val = 100;
int main()
{
// Local variable
int val = 200;
// These variables can be accessed from
// outside the namespace using the scope
// operator ::
cout << first::val << '\n';
return 0;
}

Does declaring variables and functions in same namespace get an error? [C++]

If I create a namespace Maths and use another library with a namespace named Maths, will I get an error for re-declaring a variable like PI or re-defining a function like add?
I ask because if I choose to not use namespaces, I should get an error for doing those things, right?
If I don't get an error using namespaces but I do when not using namespaces, isn't safer to just not use namespaces?
Thanks for your time.
First thing, namespace must be global and In different namespace you can have same function or variable, but in same namespace you can't have same variable declaration twice.
namespace A {
int i=10;
char i ='a';/** is not valid **/
void print() {
...
}
}
namespace B {
float i = 1.5; /** valid **/
void print() { /** valid **/
...
}
}
In above example in namespace A and B you have i of int type and i of float type respectively which is valid but In namespace A itself you can't have variable i of different types (considered as re-declaration)
Decided to test it myself:
//in file testnamespace.h
namespace test
{
int t = 1;
void fooo(){};
}
//in file testnamespace2.h
namespace test
{
int t=10000;
void fooo(){int x = -2;}
}
//in file test.cpp
#include "testnamespace.h"
#include "testnamespace2.h"
int main()
{
int ayyyeee = test::t;
foo();
return 0;
}
This gives an error for redefinition,multiple initialization.
All I was looking for.

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 access static members of a class?

I am starting to learn C++ and Qt, but sometimes the simplest code that I paste from a book results in errors.
I'm using g++4.4.2 on Ubuntu 10.04 with QtCreator IDE. Is there a difference between the g++ compiler syntax and other compilers? For example when I try to access static members something always goes wrong.
#include <iostream>
using namespace std;
class A
{
public:
static int x;
static int getX() {return x;}
};
int main()
{
int A::x = 100; // error: invalid use of qualified-name 'A::x'
cout<<A::getX(); // error: : undefined reference to 'A::x'
return 0;
}
I think it's exactly the same as declared here and here (isn't it?). So what's wrong with the above code?
You've declared the static members fine, but not defined them anywhere.
Basically what you've said "there exists some static member", but never set aside some memory for it, you need:
int A::x = 100;
Somewhere outside the class and not inside main.
Section [9.4.2]
Static Data Members
The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void. The definition for a static data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of the static data member shall be qualified by its class name using the :: operator
You need to define the static member variable of the class outside the class as static member variables require declaration as well as definition.
#include <iostream>
using namespace std;
class A
{
public:
static int x;
static int getX() {return x;}
};
int A::x; // STATIC MEMBER VARIABLE x DEFINITION
int main()
{
A::x = 100; // REMOVE int FROM HERE
cout<<A::getX();
return 0;
}
Try:
#include <iostream>
using namespace std;
class A
{
public:
// This declares it.
static int x;
static int getX(){return x;}
};
// Now you need an create the object so
// This must be done in once source file (at file scope level)
int A::x = 100;
int main()
{
A::x = 200;
// Notice no 'int' keyword before A::x on this line. You can modify A::x
cout<<A::getX(); // Should work
return 0;
}
The definition of static member variables must live at file scope, i.e. outside all functions, etc.
Try this example:
#include<iostream>
using namespace std;
class check
{
static int a;
public:
void change();
} ;
int check::a=10;
void check::change()
{
a++;
cout<<a<<"\n";
}
int main()
{
int i,j;
check c;
check b;
c.change();
b.change();
return 0;
}
Now you have worked out how to use static class members I will advise you that you should generally use them only in the following circumstances:
For use in templates. So in your example you could have GetX() in different classes and in a template somewhere you would use
template< typename T >
int func()
{
return T::GetX();
}
although obviously more elaborate. But here your static function being in a class serves a purpose.
Where the function needs access to the class, i.e. to private members. You could make it a friend but you may as well make it static. Often the case in callbacks.
The rest of the time you can probably use compilation-unit level functions and variables which has the advantage of taking your members out of the header (particularly if they are private). The less implementation detail you give the better.
You can use the inline keyword since c++ 17 in front of static members to avoid a definition outside of class scope. Your code should now look like this:
#include <iostream>
using namespace std;
class A
{
public:
inline static int x;
static int getX() {return x;}
};
int main()
{
A::x = 100; //Works now
cout<<A::getX()<<'\n';
return 0;
}
Case 1: static variable
As we all know, defining a static variable inside a class which will throw compilation error. E.g. below
class Stats
{
public:
static int AtkStats[3];
*static int a =20;* // Error: defining a value for static variable
};
int Stats::AtkStats[3] = {10, 0, 0};
Output:
error: ISO C++ forbids in-class initialization of non-const static member 'Stats::a'
Case 2: const static variable
For const static variable, we can define a value either inside a class or Outside class.
class Stats
{
public:
static const int AtkStats[3];
static const int a =20; // Success: defining a value for a const static
};
const int Stats::AtkStats[3] = {10, 0, 0};
const int Stats::a = 20; // we can define outside also
Output:
Compilation success.