Hi Anyone,

I found following strange problem writing a C++ code in VS.2005.

Say we have a class A having inside its scope locally defined function
a() (by default it should have inline attribute AFAIK). Then inside
a() I define locally class B with function b().
Finally if the header file is included in more than one cpp files I
get linker error LNK2005 that B::b() has multiple definitions.
Now If I move B outside the scope of a() to the scope of A then the
problem is gone.

Is that proper behavior of the compiler/linker according to C++
standard or a bug?
Are the functions defined in inside local classes considered inline as
well by default?

Best regards,
B.

Re: VC++.2005 locally defined class's member functions generate LNK2005 by Alf

Alf
Mon Jul 21 07:29:12 CDT 2008

* bdachev@gmail.com:
> Hi Anyone,
>
> I found following strange problem writing a C++ code in VS.2005.
>
> Say we have a class A having inside its scope locally defined function
> a() (by default it should have inline attribute AFAIK). Then inside
> a() I define locally class B with function b().
> Finally if the header file is included in more than one cpp files I
> get linker error LNK2005 that B::b() has multiple definitions.
> Now If I move B outside the scope of a() to the scope of A then the
> problem is gone.
>
> Is that proper behavior of the compiler/linker according to C++
> standard or a bug?

AFAICS it's a bug.

Code that produces this error compiles fine with g++.

The standard only prohibits static data members in a local class.


> Are the functions defined in inside local classes considered inline as
> well by default?

Yes, but it's little tricky: per the current standard a local class does not
have linkage. It's not internal linkage, it's not external linkage, it's no
linkage (no linkage essentially means "cannot be referred to from other
scopes"). E.g. you can't use it as a template parameter.

I think that's where Visual C++ stumbles.


Cheers, & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Re: VC++.2005 locally defined class's member functions generate by bdachev

bdachev
Mon Jul 21 08:24:35 CDT 2008

Hi Alf,

> > Is that proper behavior of the compiler/linker according to C++
> > standard or a bug?
>
> AFAICS it's a bug.
>
> Code that produces this error compiles fine with g++.

Yeah! I just tried that too and no errors on g++.

> The standard only prohibits static data members in a local class.
>
> > Are the functions defined in inside local classes considered inline as
> > well by default?
>
> Yes, but it's little tricky: per the current standard a local class does not
> have linkage. It's not internal linkage, it's not external linkage, it's no
> linkage (no linkage essentially means "cannot be referred to from other
> scopes"). E.g. you can't use it as a template parameter.
>
> I think that's where Visual C++ stumbles.

I also tried to use class locally defined in function as a template
argument in VS.2005 and it compiles with no errors. So once again
there is a problem following the C++ standard!

Cheers,
B.

Re: VC++.2005 locally defined class's member functions generate LNK2005 error by Doug

Doug
Mon Jul 21 10:44:42 CDT 2008

On Mon, 21 Jul 2008 05:04:02 -0700 (PDT), bdachev@gmail.com wrote:

>Hi Anyone,
>
>I found following strange problem writing a C++ code in VS.2005.
>
>Say we have a class A having inside its scope locally defined function
>a() (by default it should have inline attribute AFAIK).

If sounds like you're describing a non-static member function defined
inside the class body. Member functions defined inside the class body are
implicitly inline.

>Then inside a() I define locally class B with function b().

That's indeed a "local" class.

>Finally if the header file is included in more than one cpp files I
>get linker error LNK2005 that B::b() has multiple definitions.
>Now If I move B outside the scope of a() to the scope of A then the
>problem is gone.
>
>Is that proper behavior of the compiler/linker according to C++
>standard or a bug?

Sounds like a bug.

>Are the functions defined in inside local classes considered inline as
>well by default?

It is required that you define them inside the class definition; there is
no syntax for defining them outside. This implies they're "inline".
However, unlike ordinary inline functions, being members of a local class,
they don't have linkage. FWIW, the following program compiles fine in VC
2008:

// a.h

struct A
{
void f()
{
struct B
{
void g()
{
}
};

B b;
b.g();
}
};

void h();

// a.cpp

#include "a.h"

int main()
{
A a;
a.f();
h();
}

// b.cpp

#include "a.h"

void h()
{
A a;
a.f();
}

X>cl -W4 a.cpp b.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for
80x86
Copyright (C) Microsoft Corporation. All rights reserved.

a.cpp
b.cpp
Generating Code...
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.

/out:a.exe
a.obj
b.obj

X>

--
Doug Harrison
Visual C++ MVP

Re: VC++.2005 locally defined class's member functions generate LNK2005 error by Igor

Igor
Mon Jul 21 12:13:29 CDT 2008

bdachev@gmail.com wrote:
>> Yes, but it's little tricky: per the current standard a local class
>> does not have linkage. It's not internal linkage, it's not external
>> linkage, it's no linkage (no linkage essentially means "cannot be
>> referred to from other scopes"). E.g. you can't use it as a template
>> parameter.
>>
>> I think that's where Visual C++ stumbles.
>
> I also tried to use class locally defined in function as a template
> argument in VS.2005 and it compiles with no errors. So once again
> there is a problem following the C++ standard!

The upcoming C++0x standard will reportedly allow local classes as
template arguments.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2402.pdf
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm

This is deemed important to encourage using STL algorithms like for_each
in place of hand-written loops. As it stands now, local class can't be
used as a functor in for_each and has to be moved out of the function,
which makes the code less readable since the "body of the loop" is now
far away from surrounding code.

Apparently, authors of VC2005 attempted to implement this feature as an
extension, but didn't quite take all the consequences into account and
broke something else in the process. Accoring to Doug, this appears to
have been fixed in VC2008.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: VC++.2005 locally defined class's member functions generate by bdachev

bdachev
Mon Jul 21 17:37:03 CDT 2008

Hi Doug,

> It is required that you define them inside the class definition; there is
> no syntax for defining them outside. This implies they're "inline".
> However, unlike ordinary inline functions, being members of a local class,
> they don't have linkage. FWIW, the following program compiles fine in VC
> 2008:

Sorry I didn't have VC 2008 to test. Good to read that it is fixed
there!

Best regards,
B.

Re: VC++.2005 locally defined class's member functions generate by bdachev

bdachev
Mon Jul 21 17:40:56 CDT 2008

Hi Igor,

> The upcoming C++0x standard will reportedly allow local classes as
> template arguments.
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2402.pdf
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm
>
> This is deemed important to encourage using STL algorithms like for_each
> in place of hand-written loops. As it stands now, local class can't be
> used as a functor in for_each and has to be moved out of the function,
> which makes the code less readable since the "body of the loop" is now
> far away from surrounding code.
>
> Apparently, authors of VC2005 attempted to implement this feature as an
> extension, but didn't quite take all the consequences into account and
> broke something else in the process. Accoring to Doug, this appears to
> have been fixed in VC2008.

Actually it all started from trying to use local class as a template
argument.
I also embrace the idea of the proposal above!

Thank you all guys for sharing your knowledge!

Best wishes,
B.