local class problem

R

Rahul

Hi,

I have the following code and i get a compilation error,

int main()
{
class Locale
{
public:
static int c;
};
return(0);
}

saying it is "illegal to have a static member in a local class", what
is the reason? What if i want to use the variable only inside the
function?

Thanks in advance ! ! !
 
B

Barry

Rahul said:
Hi,

I have the following code and i get a compilation error,

int main()
{
class Locale
{
public:
static int c;
};
return(0);
}

saying it is "illegal to have a static member in a local class", what
is the reason? What if i want to use the variable only inside the
function?

Without checking the standard,
I guess that local class has no linkage,
while static member needs a linkage.
they just conflict.

But I don't will this be changed in the coming standard.
as local class can be used as template parameter.
(see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2402.pdf)
 
L

Looney

Without checking the standard,
I guess that local class has no linkage,
while static member needs a linkage.
they just conflict.

But I don't will this be changed in the coming standard.
as local class can be used as template parameter.
(seehttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2402.pdf)
Like Barry said Member functions
of a local class have no linkage,where as static objects have internal
linkage
which conflicts and as a result you get a compiler error.
to solve the issue just try declaring a static int outside
the local class for whatever u are trying to do achieve with it.
 
R

Rahul

Like Barry said Member functions
of a local class have no linkage,where as static objects have internal
linkage
which conflicts and as a result you get a compiler error.
to solve the issue just try declaring a static int outside
the local class for whatever u are trying to do achieve with it.

Fine, but i guess static member variables have external linkage (as
long as a header file is included in the other files), its just like
global variables without polluting the global namespace.

Second, i'm able to have static member functions in the local
class...
 
J

Juha Nieminen

Rahul said:
Second, i'm able to have static member functions in the local
class...

I don't think you are unless they are inline (implementing the
function inside the class declaration makes it implicitly inline).

I don't think it's possible to make static member variables "inline"
in any way, in the same sense as static member functions.

The usual way to have "local" classes is to put them inside a nameless
namespace. They will then be local to the current compilation unit,
which is usually enough.
 
J

James Kanze

Rahul wrote:
Without checking the standard, I guess that local class has no
linkage, while static member needs a linkage. they just
conflict.

More or less. A local class doesn't have linkage, so it cannot
be named elsewhere, and everything in it must be defined in the
class itself. The declaration of a static variable inside a
class is not a definition; it requires a definition elsewhere.
But I don't will this be changed in the coming standard.
as local class can be used as template parameter.
(seehttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2402.pdf)

Somehow, I doubt it. I've not read the paper through in detail,
but it starts out with "all local types and unnamed types have a
`name for linkage purposes'" that is created by the compiler."
This sounds very much like the name of an anonymous namespace,
which can't be named by the programmer. If this is the case,
then you still have no way of defining the variable. (I also
don't know the status of this proposal, whether it has been
accepted, or is likely to be, or not.)
 
S

Stefan Ram

James Kanze said:
The declaration of a static variable inside a class

specifier
is not a definition; it requires a definition elsewhere.

But if the type of a variable is »int«, the variable
also can be defined within the class specifier.
 
S

Stefan Ram

But if the type of a variable is »int«, the variable
also can be defined within the class specifier.

Correction: This holds only for static /const/ fields.
 
S

sk_usenet

Stefan Ram said:
Correction: This holds only for static /const/ fields.

Strictly speaking, statement made by James is correct.

Section 9.4.2/4
"If a static data member is of const integral or const enumeration type, its
declaration in the class definition can specify a constant-initializer which
shall be an integral constant expression. In that case, the member can
appear in integral constant expressions within its scope. **The member shall
still be
defined in a namespace scope if it is used in the program and the namespace
scope definition shall not contain an initializer.** "

Here *used* in the program means that the static const member is treated
like an l-value.
 
J

James Kanze

But if the type of a variable is »int«, the variable
also can be defined within the class specifier.

Not according to the standard. Even if an initializer is
present, the declaration in the class is not a definition.
(This is the only case in the language, I think, where an
initializer is present on something that is not a definition.)
According to the standard, it must be defined once and only once
in the program if it is used. According to the original
standard, it is used if its name appears in a potentially
evaluated expression; the latest draft changes this to exclude
cases where the object "satisfies the requirements for appearing
in a constant expression and the lvalue-to-rvalue conversion is
immediately applied."

Not providing a definition (or providing more than one) is
undefined behavior, of course, which means that the
implementation is not required to emit an error message. The
language added to the latest draft corresponds to a case where
(as far as I know) no implementation actually did emit an error
message. If you take the address of the static variable, even
indirectly (e.g. by binding it to a reference), then you will
generally have to provide a definition.

Try the following:

#include <iostream>

struct S
{
static int const i = 47 ;
} ;

void
f( int const& i )
{
std::cout << i << std::endl ;
}

int
main()
{
f( S::i ) ;
return 0 ;
}

It fails to compile (actually, fails to link) with the compilers
available to me (g++, VC++ and Sun CC).

Note too that while typically, one would declare f, above, to
take a value rather than a reference, references can appear
because of templates, e.g. std::vector<int>::push_back() takes a
reference to int. In such cases, it's likely that whether the
compiler complains depends on the optimization level, or more
precisely, whether it actually inlines push_back or not).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,175
Messages
2,570,946
Members
47,497
Latest member
PilarLumpk

Latest Threads

Top