From: Johannes Schaub (litb) on
Seungbeom Kim wrote:

> Johannes Schaub (litb) wrote:
>> 萌 朱 wrote:
>>
>>> #include <iostream>
>>> #include <typeinfo>
>>> using namespace std;
>>>
>>> typedef int T;
>>> T a, (*(*b)(T))(T);
>>>
>>> int main (int argc, char** argv)
>>> {
>>> typedef double T;
>>> T(a), (*(*b(T)))(T);
>>>
> [...]
>>> }
>>>
>>
>> It declares "b" in global namespace declarative region as a function
>> taking an int and returning a pointer to such a function.
>
> Not as a function, but as a pointer object, if the OP really wrote
> what was meant.
>
Oops, i'm sorry. For sure i wanted to write pointer to it :)

>> And it declares "b" in
>> the block declarative region of main as a function taking int and
>> returning a pointer to a pointer to such a function.
>
> Isn't it as a function taking double?
>
Right again :) Silly me.

>> It says however in 3.3/4: "Given a set of declarations in a single
>> declarative region, each of which specifies the same unqualified name,
>> ... they shall all refer to the same entity, or all refer to functions
>> and function templates; or [some case with classes hiding functions]" and
>> "[Note: these restrictions apply to the declarative region into which a
>> name is introduced, which is not necessarily the same as the region in
>> which the declaration occurs.]". In your case, one is the name of an
>> object (function pointer), and the other the name of a function.
>
> Which entities are you referring to? The 'b' in the global namespace
> scope and the other 'b' in the local scope defined by main()?
> Do their declarations constitute "a set of declarations in a *single*
> declarative region, each of which specifies the same unqualified name"
> (emphasis mine)? If they are interpreted so, it would make name hiding
> basically impossible, wouldn't it?
>

Yes, they do constitute that. The wording seems to mean the region in which
the declaration occurs in the program text first, but the note does clarify
the region in which the name is introduced (i.e "declared into") is meant
(and the one the declaration appears lexically in is of no importance).

The second case that I just put in "[...]" does allow a set of function
names hide a class or enumeration name, and the first case i quoted fully
allows the declarations if they all refer to functions or function
templates.

The following goes fine, because both declarations introduce names into
different declarative regions (the first into the one of the global
namespace, and the second one into the block, where also its declaration
appears lexically).

int a; int main() { int a; }

It helped me to think of "declarative region" as a block / class body /
namespace body / function prototype etc, and "scope" as the part of these
declarative regions in which a name is visible to unqualified lookup. Each
declarative region has a scope, and the scope of a name/declaration is the
union of the parts of one or more of these scopes: For instance, a member
declaration's declarative region is its class body it appears in, but the
(potential) scope it is a member of includes default arguments, ctor-
initializer and function bodies.

In general, a declaration introduces a name into the scope in which the
declaration occurs (i.e a using declaration introducing a name into the
declarative region where it appears also introduces a name into the scope in
which it appears) according to 3.3/3. But this behavior is tweaked for
certain declarations, including for using directives, friend declarations
and stuffs.

In a local function declaration, we also introduce a name into the scope in
which the declaration appears, but introduce a name into the declarative
region of the nearest enclosing namespace (and do not introduce a name into
the scope of it).


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Seungbeom Kim on
Johannes Schaub (litb) wrote:
> Seungbeom Kim wrote:
>
>> Johannes Schaub (litb) wrote:
>>> It says however in 3.3/4: "Given a set of declarations in a single
>>> declarative region, each of which specifies the same unqualified name,
>>> ... they shall all refer to the same entity, or all refer to functions
>>> and function templates; or [some case with classes hiding functions]" and
>>> "[Note: these restrictions apply to the declarative region into which a
>>> name is introduced, which is not necessarily the same as the region in
>>> which the declaration occurs.]". In your case, one is the name of an
>>> object (function pointer), and the other the name of a function.
>> Which entities are you referring to? The 'b' in the global namespace
>> scope and the other 'b' in the local scope defined by main()?
>> Do their declarations constitute "a set of declarations in a *single*
>> declarative region, each of which specifies the same unqualified name"
>> (emphasis mine)? If they are interpreted so, it would make name hiding
>> basically impossible, wouldn't it?
>>
>
> Yes, they do constitute that. The wording seems to mean the region in which
> the declaration occurs in the program text first, but the note does clarify
> the region in which the name is introduced (i.e "declared into") is meant
> (and the one the declaration appears lexically in is of no importance).
>
> The second case that I just put in "[...]" does allow a set of function
> names hide a class or enumeration name, and the first case i quoted fully
> allows the declarations if they all refer to functions or function
> templates.
>
> The following goes fine, because both declarations introduce names into
> different declarative regions (the first into the one of the global
> namespace, and the second one into the block, where also its declaration
> appears lexically).
>
> int a; int main() { int a; }

That's what I meant: whether the two declarations constitute a set of
declarations in a *single* declarative region, each of which specifies
the same unqualified name. If we interpret them as such, then 3.3/4
states that they shall all refer to the same entity, but they don't.
Since we obviously know the above code is correct, then we have to
conclude that the two declarations don't constitute such a set, and
that they are not in a *single* declarative region.

The declarative region of the global declaration is the entire code
shown above, and that of the local declaration is the block between
{ and }. The wording is a bit ambiguous, because we could say the
two declarations are definitely in a single declarative region which
is the entire code, but we could also say the the declarations span
multiple declarative region and that they are not in a single one.
My guess is that we have to interpret 3.3/4 as the latter, so that
the name hiding example would be valid.

--
Seungbeom Kim

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: 萌 朱 on
On Dec 20, 9:47 am, Seungbeom Kim <musip...(a)bawi.org> wrote:
> Johannes Schaub (litb) wrote:
> > Seungbeom Kim wrote:
>
> >> Johannes Schaub (litb) wrote:
> >>> It says however in 3.3/4: "Given a set of declarations in a single
> >>> declarative region, each of which specifies the same unqualified name,
> >>> ... they shall all refer to the same entity, or all refer to functions
> >>> and function templates; or [some case with classes hiding functions]" and
> >>> "[Note: these restrictions apply to the declarative region into which a
> >>> name is introduced, which is not necessarily the same as the region in
> >>> which the declaration occurs.]". In your case, one is the name of an
> >>> object (function pointer), and the other the name of a function.
> >> Which entities are you referring to? The 'b' in the global namespace
> >> scope and the other 'b' in the local scope defined by main()?
> >> Do their declarations constitute "a set of declarations in a *single*
> >> declarative region, each of which specifies the same unqualified name"
> >> (emphasis mine)? If they are interpreted so, it would make name hiding
> >> basically impossible, wouldn't it?
>
> > Yes, they do constitute that. The wording seems to mean the region in which
> > the declaration occurs in the program text first, but the note does clarify
> > the region in which the name is introduced (i.e "declared into") is meant
> > (and the one the declaration appears lexically in is of no importance).
>
> > The second case that I just put in "[...]" does allow a set of function
> > names hide a class or enumeration name, and the first case i quoted fully
> > allows the declarations if they all refer to functions or function
> > templates.
>
> > The following goes fine, because both declarations introduce names into
> > different declarative regions (the first into the one of the global
> > namespace, and the second one into the block, where also its declaration
> > appears lexically).
>
> > int a; int main() { int a; }
>
> That's what I meant: whether the two declarations constitute a set of
> declarations in a *single* declarative region, each of which specifies
> the same unqualified name. If we interpret them as such, then 3.3/4
> states that they shall all refer to the same entity, but they don't.
> Since we obviously know the above code is correct, then we have to
> conclude that the two declarations don't constitute such a set, and
> that they are not in a *single* declarative region.
>
> The declarative region of the global declaration is the entire code
> shown above, and that of the local declaration is the block between
> { and }. The wording is a bit ambiguous, because we could say the
> two declarations are definitely in a single declarative region which
> is the entire code, but we could also say the the declarations span
> multiple declarative region and that they are not in a single one.
> My guess is that we have to interpret 3.3/4 as the latter, so that
> the name hiding example would be valid.
>
> --
> Seungbeom Kim
>

I think the standard is clear.

For the case, int a; int main() { int a; }

I do not have a standard, but I got this from the current working
draft (3.3/1) "Every name is introduced in some portion of program
text called a declarative region, which is the largest part of the
program in which that name is valid, that is, in which that name may
be used as unqualified name to refer to the same entity." This is to
say the declarative region of the global a is the entire program
excluding the declarative region of the local a which is between
{ and }. Therefore, those two a's are in different declarative
regions, so (3.3/4) should not apply to them which makes this case
does not violate the standard.

For my program, the local b is a function declaration which, according
to (3.5/7), should be a member of the inner most enclosing namespace,
i.e., the global namespace. The global b, which is a pointer object,
however, is also in global namespace. Therefore, they are considered
in the same declarative region since they are all members of the
global namespace. Now, (3.3/4) applies to this case which makes my
program violate the standard.

BTW, I got this out of a typo when I was testing something else and
that is why it seems weird and does not bear obvious practical
purpose. I do not understand the nature of the problem on the very
beginning, so I try to be careful and what I put here is exactly what
I feed to the compiler. Thank you for all your discussions, they
really promote my understanding for C++, ^_^.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Johannes Schaub (litb) on
萌 朱 wrote:

> On Dec 20, 9:47 am, Seungbeom Kim <musip...(a)bawi.org> wrote:
>> Johannes Schaub (litb) wrote:
>> > Seungbeom Kim wrote:

>> >> Johannes Schaub (litb) wrote:
>> >>> It says however in 3.3/4: "Given a set of declarations in a single
>> >>> declarative region, each of which specifies the same unqualified
>> >>> name, ... they shall all refer to the same entity, or all refer to
>> >>> functions and function templates; or [some case with classes hiding
>> >>> functions]" and "[Note: these restrictions apply to the declarative
>> >>> region into which a name is introduced, which is not necessarily the
>> >>> same as the region in which the declaration occurs.]". In your case,
>> >>> one is the name of an object (function pointer), and the other the
>> >>> name of a function.
>> >> Which entities are you referring to? The 'b' in the global namespace
>> >> scope and the other 'b' in the local scope defined by main()?
>> >> Do their declarations constitute "a set of declarations in a *single*
>> >> declarative region, each of which specifies the same unqualified name"
>> >> (emphasis mine)? If they are interpreted so, it would make name hiding
>> >> basically impossible, wouldn't it?

>> > Yes, they do constitute that. The wording seems to mean the region in
>> > which the declaration occurs in the program text first, but the note
>> > does clarify the region in which the name is introduced (i.e "declared
>> > into") is meant (and the one the declaration appears lexically in is of
>> > no importance).

>> > The second case that I just put in "[...]" does allow a set of function
>> > names hide a class or enumeration name, and the first case i quoted
>> > fully allows the declarations if they all refer to functions or
>> > function templates.

>> > The following goes fine, because both declarations introduce names into
>> > different declarative regions (the first into the one of the global
>> > namespace, and the second one into the block, where also its
>> > declaration appears lexically).

>> > int a; int main() { int a; }

>> That's what I meant: whether the two declarations constitute a set of
>> declarations in a *single* declarative region, each of which specifies
>> the same unqualified name. If we interpret them as such, then 3.3/4
>> states that they shall all refer to the same entity, but they don't.
>> Since we obviously know the above code is correct, then we have to
>> conclude that the two declarations don't constitute such a set, and
>> that they are not in a *single* declarative region.

>> The declarative region of the global declaration is the entire code
>> shown above, and that of the local declaration is the block between
>> { and }. The wording is a bit ambiguous, because we could say the
>> two declarations are definitely in a single declarative region which
>> is the entire code, but we could also say the the declarations span
>> multiple declarative region and that they are not in a single one.
>> My guess is that we have to interpret 3.3/4 as the latter, so that
>> the name hiding example would be valid.

> I think the standard is clear.

> For the case, int a; int main() { int a; }

> I do not have a standard, but I got this from the current working
> draft (3.3/1) "Every name is introduced in some portion of program
> text called a declarative region, which is the largest part of the
> program in which that name is valid, that is, in which that name may
> be used as unqualified name to refer to the same entity." This is to
> say the declarative region of the global a is the entire program
> excluding the declarative region of the local a which is between
> { and }. Therefore, those two a's are in different declarative
> regions, so (3.3/4) should not apply to them which makes this case
> does not violate the standard.


This interpretation is against the example in 3.3/2 which says "The
declarative region of the first j includes the entire example.". To me all
the stuff about "declarative region" and "scope" seem not exactly
consistent. I think
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#554
is a nice DR handling it.

To me it would be most natural if "declarative region" was a layer with
slots where names are mounted into, and registered with properties like
name, the classification (class-name, enumeration-name etc...) and
(visibility, declaration-reference). If the name's "visibility" is true,
then it's also got a potential scope by being able to be found by
unqualified name-lookup in certain parts of the program text (if we connect
declarative regions to the program code (like with "class body", "block",
etc...), then we may give declarative regions a scope, and names are then
part of the scopes of declarative regions).

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]