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?

Was it helpful?

Solution

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

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top