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.
Related
This question already has answers here:
Why can't member initializers use parentheses?
(2 answers)
Closed 4 years ago.
I'm sorry, I haven't programmed C++ in a while, I'd like to refresh my knowledge about what exact rule I'm violating here:
I can do:
int main()
{
int a(5);
}
but cannot do:
struct Foo
{
int a(5); // Error: expected a type specifier / Error: syntax error, 'constant'
}
I am trying to regain some lost knowledge, can someone direct me to the rule that disallows this? I'm pretty sure there'd be a question about it on here, I couldn't find it. The only thing I remember is that the committee debated (for C++11 I think) in class constructor arguments and introduced new squiggly bracket constructor initialisers, like int a{5}; but I would like to know why int a(5); isn't allowed inside a class. Has this always been disallowed in C++?
A species of vexing parse. Names in default member initializers are supposed to be looked up in the completed class, because they are suppose to imitate constructor initializers. With (), the compiler won't be able to figure out what it's parsing, because it can refer to things declared later in the class:
struct X {
int f(x); // function or data member?
static const int x = 1;
};
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I found Why/when should I declare a variable using static?, but the tags is about objective-c .
I can't make sure is there any difference in usage details between c++ and objective-c when you use static, so when/why should I use static in c++?
static has a couple of independent meanings, depending on context.
void f() { ... }
static void g() { ... }
Here, f has "external linkage", which means that its name is visible in other translation units. That is, in another source file you could have void f(); and then you could call the function f.
g, on the other hand, because it's marked static, has "internal linkage". You can call it from code in the same source file, but you cannot call it from another source file.
Same for objects:
int i = 3; // external linkage
static int j = 4; // internal linkage
And a small complication: you can define a static object inside a function.
void f() {
static int i = 3;
std::cout << i << '\n';
++i;
}
Here, i has no linkage. It's only visible inside the function. It gets initialized the first time the function is called (and doesn't get initialized at all if the function isn't called). So the first time that f is called it will write "3" to the console. On the second call it will write "4", etc. Understanding the behavior of objects with destructors is left as an exercise for the reader.
Inside a class definition it's completely different.
class C {
public:
void f();
static void g();
int i;
static int j;
};
Here, when you call f you must call it on an object of type C, and f can use data members of that object, that is, it can look at and change both i and j. When you call g there is no associated object. It's still a member of C, so it can look at and change j, because j, too, is not associated with any object. There's only one j, and it's shared by all objects of type C.
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.
This question already has answers here:
When should I write the keyword 'inline' for a function/method?
(16 answers)
Closed 9 years ago.
I am trying to completely understand what inline does but I get confused when it comes to constructors. So far I understood that inlining a function will put the function in the place it is called:
class X {
public:
X() {}
inline void Y() { std::cout << "hello" << std::endl; }
};
int main() {
X x;
x.Y; //so instead of this it will be: "std::cout << "hello" << std::endl;"
}
But what will this do (how does this get replaced?):
class X {
public:
//or inline if the compilers feeling friendly for this example
__forceinline X() {}
}
The meaning of inline is just to inform the compiler that the finction in question will be defined in this translation as well as possibly other translation units. The compiler uses this information for two purposes:
It won't define the function in the translation unit as an externally visible, unique symbol, i.e., you won't get an error about the symbol being defined multiple times.
It may change its view on whether it wants to call a function to access the finctionality or just expand the code where it is used. Whether it actually will inline the code will depend on what the compiler can inline, what it thinks may be reasonable to inline, and possibly on the phase of the moon.
There is no difference with respect to what sort of function is being inlined. That is, whether it is a constructor, a member function, a normal function, etc.
BTW, member functions defined inside the class definition are implicitly declared inline. There is no need to mention it explicitly. __forecedinline seems to be a compiler extension and assuming it does what it says is probably a bad idea as compilers are a lot better at deciding on what should be inlined than humans.
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.