In this code i has been defined (and it has been initialized despite being extern). Now the book I am reading says:
An extern declaration may be defined only if it appears to be
outside a function.
and it offers no reason behind it.
#include<iostream>
using namespace std;
int main()
{
extern int i=898;
cout<<i<<endl;
return 0;
}
I have gone through the question (similar to this one on Stack Overflow) but the explanation doesn't appear to be clear. The question is:
How are these two definitions different at function scope:
int i=898;
extern int i=898;
In both the cases a single unit of int size memory is being allocated. Is it due to linking error? Please answer clearly as (IMO) it hasn't been satisfactorily in older version whose reference has been used to mark this as duplicate.
The extern keyword keeps the compiler from allocating memory for the variable indicating that memory for the variable will be resolved at link time in global scope. Your link to the other answer was not available so I answered.
Related
This question already has answers here:
static and extern global variables in C and C++
(2 answers)
Closed 2 years ago.
test1.hpp
struct obj{
obj(){}
~obj(){cout<<"destroyed"<<endl;}
};
static obj x;
test1.cpp
#include "test1.hpp"
main.cpp
#include "test1.hpp"
int main(){...}
the destructor is getting called twice, why is this happening?
gcc-7.5.0
os-ubuntu
why is this happening?
Because the variable is declared static. This means that the variable has internal linkage. Which means that each translation unit has their own object. You have defined the variable in two translation units, and therefore you have two objects.
If you didn't want this, then the variable shouldn't be static. An easy solution is to declare it inline instead. This allows it to have external linkage while still being defined in the header.
P.S. Be very careful of Static Initialisation Order Fiasco. Try to avoid variables of static storage when you can, especially those in namespace scope.
You have two static variables with the internal linkage due to defining the corresponding object in the header
struct obj{
obj(){}
~obj(){cout<<"destroyed"<<endl;}
};
static obj x;
This header is included in two modules test1.cpp and main.cpp. So each module has its own static variable x.
If you want to have one object with the external linkage then declare it in the header like
extern obj x;
and define it in one of modules like
obj x;
This question already has answers here:
Static variables in member functions
(4 answers)
The static keyword and its various uses in C++
(9 answers)
Closed 3 years ago.
I am studying for my finals and there is a topic which is bugging me recently i don't understand why we use static variables or static data members in our code. Can anyone explain it to me how and why we use the static keyword in C++
I have tried looking it up on different sites and i have tried some code, what i don't understand is why am i getting such results.
class myclass {
public:
int a,b;
inline int getVal();
};
inline int myclass :: getVal()
{
cout<<"Enter the value of a and b\n";
static int a = 9; //static keyword used.
cin>>a>>b;
}
int main()
{
myclass o1;
o1.getVal();
cout<<"\nThe value of a is : "<<o1.a<<"\nThe value of b is : "<<o1.b;
}
the value i am getting for a is 3, no matter what i enter? can anyone explain to me why is that?
The meaning of static is this: When a variable is declared as static, space for it gets allocated for the lifetime of the program. Even if the function is called multiple times, space for the static variable is allocated only once and the value of variable in the previous call gets carried through the next function call.
Starting point
The static keyword means that a variable is bound to a class itself instead of an object of the class.
If it is not declared as static it can be changed for each object of the class individually whereas if you change a static variable of a class it is set to the new value for all of its objects.
I hope this helps.
If you have any questions feel free to ask.
Edit: as Bogdan Doicin pointed out in another answer static has another meaning in functions.
I will leave this up for the other meaning but if you want to accept an answer accept his because it better fits the question.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Is it true that redefinition mean that we're trying to define an entity which is already defined. This question appear from the following code example:
int a=5;
int main()
{
int a=3;//redefinition? I think no, because `int a` denote an entity different from the global "a"
}
and one more example:
int foo(){ return 1; }
int main()
{
int foo();
int a=foo();//Now a is 1
}
We can't define just declared foo() function inside the main() function body, but if we can will it be a redefinition?
Local variables might shadow global ones, that's what the :: scope resolution operator is for
#include <iostream>
using namespace std;
int a=5;
int main()
{
int a=3;
cout << a; // 3
cout << ::a; // 5
}
so no ODR problems here.
As for the second example the function declaration inside another function (when it doesn't get confused by the most-vexing-parse), I recommend this question: Is there a use for function declarations inside functions?
And: no, you can't redefine your function inside main(). You can redeclare it (even with different parameters, thus declaring a new function) but that doesn't mean you can define it so.
There's an excellent excerpt from the wiki page which I recommend to read:
In short, the ODR states that:
In any translation unit, a template, type, function, or object can
have no more than one definition. Some of these can have any number of
declarations. A definition provides an instance.
In the entire
program, an object or non-inline function cannot have more than one
definition; if an object or function is used, it must have exactly one
definition. You can declare an object or function that is never used,
in which case you don't have to provide a definition. In no event can
there be more than one definition.
Some things, like types, templates,
and extern inline functions, can be defined in more than one
translation unit. For a given entity, each definition must be the
same. Non-extern objects and functions in different translation units
are different entities, even if their names and types are the same.
Some violations of the ODR must be diagnosed by the compiler. Other
violations, particularly those that span translation units, are not
required to be diagnosed.1
No, when dealing with redefinition, it is important to remember SCOPE. It only applies for two variables with the same name that are defined in the SAME SCOPE
In example 1, the second a is LOCAL SCOPE and is local to the function. Therefore, that is the a that is viewed and referred to until you exit the function body
No. int a = foo(); or int a = 3; , inside main(), is a new variable that is also called a.
A redefinition is an attempt to redefine the same variable, e.g.:
int a = 5;
int a = 6;
Also
int foo();
is not a definition. It's a declaration. A function definition includes { }.
Redefinition is somewhat what leads to compiler-time error.
For example:
int a;
bool a;
or
void f();
int f;
In your case there wasn't compiler-time error. It was about name hiding, scope and resolving rules.
int a = 5;
{
int a = 6; //because of { } internal a is in other scope and can be defined without error
int b = a; //b == 6
}
int b = a; //b == 5
In the last case you have two diffrent "a", each in own scope of program.
In one point of program if you use a name such "a", there is only one entity that is behind this name. If compiler can't find the best match for "a" between diffrent variants you get redifinition and error.
The first one is not a redefinition due to different scopes, just like you thought.
The second one is a redeclaration, but it's ok to redeclare something any number of times you want, though the joke gets stale with repetition.
If you allow definition of functions inside functions, you get to write all the semantics, because there ain't such yet (aside from lambdas).
For someone who did so, look at the GCC C compiler, "nested functions" and "statement expressions".
Anyway, redefintion would be an error due to the One Definition Rule.
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
Why is it giving me a linking error? I think it's OK to access static members with this->x. Logically it sounds OK. I guess an instance pointer can access what a class owns as per OOPS concepts.
You need to also define the static member variable. For example:
// in .h
class some_class {
static int v; // it's just a declaration
};
// in .cpp
int some_class::v; // here's the defination
Put declarations in your Foo.h file:
class Foo {
static int v;
};
Put defenitions in your Foo.cpp file:
int Foo::v;
Here are some explanations: Why the static data members have to be defined outside the class separately in C++, Defining static members in C++
I find it helpful to treat linking errors differently. If you do something against the rules of the language -- the compilation error will be issued, so if you get a linking error it must be not something that you've done against the rules of the language directly, rather than you've omitted something. And usually the error message tells you what exactly you have omitted.
This question already has answers here:
Using "namespace foo {" instead of explicitly qualifying outside of header files [closed]
(3 answers)
Defining namespaced member vs free functions without qualification
(2 answers)
Closed 8 years ago.
In a C++ class, we can write our members in either of two styles. We can put them inside of a namespace block, or we can fully qualify each.
Is there any reason to prefer one style over the other?
Header file looks like this (bar.h):
namespace foo
{
class Bar
{
public:
Bar();
int Beans();
};
}
Style 1 (bar.cpp) - Declarations within namespace block:
#include "bar.h"
namespace foo
{
Bar::Bar()
{
}
int Bar::Beans()
{
}
}
Style 2 (bar.cpp) - Fully qualified declarations:
#include "bar.h"
foo::Bar::Bar()
{
}
int foo::Bar::Beans()
{
}
So my question, again, is: is there any reason to prefer one style over the other?
Here's a possible answer that was posted by James Kanze in answer to another similar question. (edit: note from the comment thread, this only applies to non-member functions).
Prefer the fully qualified form (style 2).
Functions written in this style are explicitly a definition, not a declaration.
That is to say, using Style 2, if you accidentally define a function with incorrect arguments, you'll get a compiler error alerting you to that fact.
Using Style 1, if you define a function with incorrect arguments it will define a different function. It will compile fine, but you'll get a linker error explaining that the method is not defined. This will probably be harder to diagnose than the compiler error resulting from Style 2.