Enum within function, is this standard?

  • Thread starter Nils Petter Vaskinn
  • Start date
N

Nils Petter Vaskinn

I'm using an enum that's declared within a function (since I only need it
within that function.)

I can't find anything about this in "The C++ Programming Language" by
Stroustroup and I don't have the standard.

Is this legal?

// test.cpp
#include <iostream>

int main() {
enum {zero,one,two};
std::cout << zero << " " << one << " " << two << std::endl;
return 0;
}

g++ seems to think so:

$ g++ -ansi -pedantic -Wall test.cpp

Gives no output, which means no error or warnings.
 
I

Ivan Vecerina

| Is this legal?
|
| // test.cpp
| #include <iostream>
|
| int main() {
| enum {zero,one,two};
| std::cout << zero << " " << one << " " << two << std::endl;
| return 0;
| }

Yes, this is a totally legal anonymous enum declaration.

Structs and classes may be declared within a function
as well (and may also be anonymous).
The only limitation with types that are declared within
a function (rather than at namespace or class scope)
is that they cannot be used as template parameters.

hth - Ivan
 
D

Domenico Andreoli

Ivan said:
Structs and classes may be declared within a function
as well (and may also be anonymous).
The only limitation with types that are declared within
a function (rather than at namespace or class scope)
is that they cannot be used as template parameters.

so the following breaks? why?

template <typename T>
struct A
{
T t;
};

void f()
{
enum B { zero, one };
A<B> t;
}


-----[ Domenico Andreoli, aka cavok
--[ http://filibusta.crema.unimi.it/~cavok/gpgkey.asc
---[ 3A0F 2F80 F79C 678A 8936 4FEE 0677 9033 A20E BC50
 
R

Rob Williscroft

Domenico Andreoli wrote in @twister1.libero.it:
Ivan Vecerina wrote:
[micro-snip]
The only limitation with types that are declared within
a function (rather than at namespace or class scope)
is that they cannot be used as template parameters.

so the following breaks? why?

template <typename T>
struct A
{
T t;
};

void f()
{
enum B { zero, one };
A<B> t;
}

The name B doesn't have external linkage. If you consider adding:

void g()
{
enum B { three, four };
A<B> t;
}

You can see the problem, you've actually tried to create 2 types
bothe withe the same id A< no-real-name-enum >.

IOW templates base there external-linkage on the external-linkage
of there arguments.

This is how the standard was/is writen. It could have been otherwise,
but would the benefits outway the cost (for implementers this is
man-hour's of programming, for us it's more waiting for fully
conforming compiler's).

Rob.
 
I

Ivan Vecerina

Rob Williscroft said:
Domenico Andreoli wrote in @twister1.libero.it:

The name B doesn't have external linkage. If you consider adding: Exact.
IOW templates base there external-linkage on the external-linkage
of there arguments.
Which from a typical implementation's perspective means that
the name of the parameter type is mangled into (used as part of)
the name of template instanciation.
This is how the standard was/is writen. It could have been otherwise,
but would the benefits outway the cost (for implementers this is
man-hour's of programming, for us it's more waiting for fully
conforming compiler's).
Maybe, but this is debatable. Since the compiler has support for
anonymous namespaces, it knows how to generate unique names
already.

Many find this limitation is especially annoying when writing
functors and predicates:
void sortByAge(std::vector<Item>& items)
{
struct AgeCompare {
bool operator()(Item const& a, Item const&b)
{ return a.age<b.age; }
};
std::sort(items.begin(),items.end(),AgeCompare()); //error
}
Because AgeCompare has no external linkage, it has to be
moved out of the function. Ugly.

I'm pretty sure that dropping this limitation has been proposed
for the next C++ standard...

Regards,
Ivan
 
R

Rob Williscroft

Ivan Vecerina wrote in
[snip]
The name B doesn't have external linkage. If you consider adding: Exact.
IOW templates base there external-linkage on the external-linkage
of there arguments.
Which from a typical implementation's perspective means that
the name of the parameter type is mangled into (used as part of)
the name of template instanciation.
This is how the standard was/is writen. It could have been otherwise,
but would the benefits outway the cost (for implementers this is
man-hour's of programming, for us it's more waiting for fully
conforming compiler's).
Maybe, but this is debatable. Since the compiler has support for
anonymous namespaces, it knows how to generate unique names
already.

Yes, the above was an attempt at a (partial) explanation of why it
isn't currently in the standard. Not a suggestion that it isn't worth
putting in the next.

In fact gcc can already do this (at least with local classes). Also
it should be easier than for anonymous namespaces as there is already a
unique name (the function's) to base the external-linkage-name on.
Many find this limitation is especially annoying when writing
functors and predicates:
void sortByAge(std::vector<Item>& items)
{
struct AgeCompare {
bool operator()(Item const& a, Item const&b)
{ return a.age<b.age; }
};
std::sort(items.begin(),items.end(),AgeCompare()); //error
}
Because AgeCompare has no external linkage, it has to be
moved out of the function. Ugly.

I'm pretty sure that dropping this limitation has been proposed
for the next C++ standard...

I have a vague recollection of reading something about this, but I
can't remember what is covered, 1) local classes, 2) local enum's,
3) nameless classes (struct {} x;) and 4) nameless enum's. It's
probably just 1 and 2, but 3 and 4 should be doable too, but does
anybody care enough to write up the proposal and justify it to the
committee ?

Some people would like to write (vc6 users currently can):

some_template< "string-id" >;

Maybe well get that too.

All of these thing's would be nice (and useful), but there not top
of my wish list (Move semantics and unlimited template paramiters are).

Rob.
 

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,146
Messages
2,570,832
Members
47,374
Latest member
EmeliaBryc

Latest Threads

Top