Topic: Proposal for "automatic enum
Author: "John Hickin" <hickin@nortelnetworks.com>
Date: Thu, 20 Sep 2001 18:55:48 GMT Raw View
Harry Stein wrote:
>
> Proposal for "automatic enum"
>
> Many times I initialize an array and wish to refer to the array
> indices with an "automatic enum". An automatic enum is one where you
> can specify the enumerated index names without specifying a separate,
> untyped, enum.
>
> That is, suppose I have:
>
> enum MsgTypes { information, warning, error, severe_error};
>
> and elsewhere I have:
>
> char *g_szMsgTypes[] =
> {
> "Information",
> "Warning",
> "Normal error",
> "Severe error"
> };
>
Do it as the following example illustrates. Variations are possible.
Just add new ASSOC entries to enum-generator, or remove existing ones,
as needed and recompile.
Regards, John.
file enum-generator
===================
// WARNING: no include guards or #pragma once in this file
ASSOC(information,"Information")
ASSOC(warning,"Warning")
ASSOC(error,"Error")
// more as needed
file enum.h
===========
#ifndef MsgTypes_H
#define MsgTypes_H
#ifdef ASSOC
# undef ASSOC
#endif
#define ASSOC(symbol,stringValue) symbol,
enum MsgTypes {
# include "enum-generator"
MsgTypesLast
};
#undef ASSOC
const char* enumToString( MsgTypes mt );
bool stringToEnum( const char* str, MsgTypes& valueReturn );
#endif
file enum.C
===========
#include "enum.h"
#define ASSOC(symbol,stringValue) case symbol: return stringValue;
const char* enumToString( MsgTypes mt )
{
switch ( mt ) {
# include "enum-generator.h"
default: return 0;
}
}
#undef ASSOC
#define ASSOC(symbol,stringValue) if ( ::strcmp(stringValue, INstring)
== 0 ) { OUTenum = symbol; return true; }
bool stringToEnum( const char* INstring , MsgTypes& OUTenum )
{
# include "enum-generator"
return false;
}
#ifdef UNIT_TEST
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
cout << enumToString(::error) << endl;
MsgTypes mt = MsgTypesLast;
if ( stringToEnum( "Information" , mt ) ) cout << enumToString(mt) <<
endl;
}
#endif
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Steve Folly" <steve@spfweb.MY-PANTS.co.uk>
Date: Thu, 20 Sep 2001 18:56:44 GMT Raw View
"Daniel Pfeffer" <daniel.pfeffer@storlogic.co.il> wrote in message
news:9oc21g$lme$1@news.inter.net.il...
> "Harry Stein" <hstein@airmail.net> wrote in message
> news:707c5551.0109190815.5d46a335@posting.google.com...
> > Proposal for "automatic enum"
> >
> > Many times I initialize an array and wish to refer to the array
> > indices with an "automatic enum". An automatic enum is one where you
> > can specify the enumerated index names without specifying a separate,
> > untyped, enum.
> >
> > That is, suppose I have:
> >
> > enum MsgTypes { information, warning, error, severe_error};
> >
> > and elsewhere I have:
> >
> > char *g_szMsgTypes[] =
> > {
> > "Information",
> > "Warning",
> > "Normal error",
> > "Severe error"
> > };
> >
> > Often the enum and initializers are in separate files. To maintain
> > and extend this data structure, you would have to update the MsgTypes
> > enum and g_szMsgTypes array.
> >
> > Pitfalls of this are obvious. Suppose one adds several new MsgTypes
> > but gets the g_szMsgTypes size wrong:
> >
> > enum MsgTypes { new1, information, warning, error, severe_error,
> > new2, new3};
> >
> > and elsewhere I have:
> >
> > char *g_szMsgTypes[] =
> > {
> > "Information",
> > "Warning",
> > "New 1 in wrong place",
> > "Normal error",
> > "Severe error",
> > "new2" // forgot "new3" watch out for g_szMsgTypes[new3] ref!
> > };
> >
> > What I would like to see is an "automatic enum". Here is some
> > off-the-cuff syntax:
> >
> > char *g_szMsgTypes[] =
> > {
> > #Information, "Information",
> > #Warning, "Warning",
> > #New1, "Doesn't matter where we put this",
> > #NormalError, "Normal error",
> > #Severe, "Severe error",
> > #New2, "new2",
> > #New3, "new3"
> > } ;
> >
>
> A better idea, borrowed from Pascal, would be something like this:
>
> enum MsgTypes {information, warning, error, severe_error};
>
> char *g_szMsgTypes[MsgTypes] = {
> ...
> };
>
> This would declare the array to have as many elements as the enum has
> members. Elements not given explicit values would be initialised using the
> default constructor, while too many initialisers would cause a diagnostic.
>
>
As you only seem to be interested in matching strings to the enumeration
entries,
would something working along the lines of Ada's 'Image attribute be more
suitable
for the problem at hand.
The compiler could generate an array of the strings automatically? Some
switch
might be needed to say whether you wanted them generated or not?
(I'll just supply the suggestion - syntax, and names of identifiers I'll
leave to the
experts :-)
Steve Folly.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Ron Natalie <ron@sensor.com>
Date: Thu, 20 Sep 2001 20:24:54 GMT Raw View
>
> file enum-generator
> ===================
> // WARNING: no include guards or #pragma once in this file
> ASSOC(information,"Information")
> ASSOC(warning,"Warning")
> ASSOC(error,"Error")
> // more as needed
>
And if you are willing to bind your strings to the enum, you
could just stringify it:
ASSOC(Information)
ASSOC(Warning)
ASSOC(Error)
#define ASSOC(x) x,
and
#define ASSOC(x) #x,
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: hstein@airmail.net (Harry Stein)
Date: Thu, 20 Sep 2001 20:49:28 GMT Raw View
"Daniel Pfeffer" <daniel.pfeffer@storlogic.co.il> wrote in message news:<9oc21g$lme$1@news.inter.net.il>...
> "Harry Stein" <hstein@airmail.net> wrote in message
> news:707c5551.0109190815.5d46a335@posting.google.com...
> > Proposal for "automatic enum"
[snip]
>
> A better idea, borrowed from Pascal, would be something like this:
>
> enum MsgTypes {information, warning, error, severe_error};
>
> char *g_szMsgTypes[MsgTypes] = {
> ...
> };
>
> This would declare the array to have as many elements as the enum has
> members. Elements not given explicit values would be initialised using the
> default constructor, while too many initialisers would cause a diagnostic.
This is a step in the right direction (getting the size right) but the
argument against it is that it can somewhat be easily be done today
as:
enum MsgTypes {information, warning, error, severe_error,
NUMENTRYSINENUM};
char *g_szMsgTypes[NUMENTRYSINENUM] = {
...
};
It just occurred to me that my proposal was invalid since it's just
not possible to combine the initializer with the "auto" enumeration
since both would have to live in a header file (for the enum to be of
use to everyone) and that just won't work out with most "common"
models which would consider the initialized array to be multiply
defined if multiple programs included it.
So we're back to square one and I probably should not have posted my
proposal since it's really impossible (for the reasons I gave above).
Oh well.
Harry
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Christopher Eltschka <celtschk@web.de>
Date: Fri, 21 Sep 2001 03:50:38 CST Raw View
hstein@airmail.net (Harry Stein) writes:
> "Daniel Pfeffer" <daniel.pfeffer@storlogic.co.il> wrote in message news:<9oc21g$lme$1@news.inter.net.il>...
> > "Harry Stein" <hstein@airmail.net> wrote in message
> > news:707c5551.0109190815.5d46a335@posting.google.com...
> > > Proposal for "automatic enum"
> [snip]
> >
> > A better idea, borrowed from Pascal, would be something like this:
> >
> > enum MsgTypes {information, warning, error, severe_error};
> >
> > char *g_szMsgTypes[MsgTypes] = {
> > ...
> > };
> >
> > This would declare the array to have as many elements as the enum has
> > members. Elements not given explicit values would be initialised using the
> > default constructor, while too many initialisers would cause a diagnostic.
>
> This is a step in the right direction (getting the size right) but the
> argument against it is that it can somewhat be easily be done today
> as:
>
> enum MsgTypes {information, warning, error, severe_error,
> NUMENTRYSINENUM};
>
> char *g_szMsgTypes[NUMENTRYSINENUM] = {
> ...
> };
Not if it is implemented as in Pascal:
"d_szMsgTypes[information]" would be valid, but "d_szMsgTypes[0]"
would be an error. As would be
enum RGBColor { red, green, blue };
enum CMYKColor { cyan, magenta, yellow, black };
colornames[RGBColor] = { "red", "green", "blue" };
char const* s = colornames[cyan];
// would be error with extension
// would initialize s to "red" with workaround
[...]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Marcin 'Qrczak' Kowalczyk" <qrczak@knm.org.pl>
Date: Fri, 21 Sep 2001 18:52:07 GMT Raw View
Wed, 19 Sep 2001 23:17:39 GMT, Sektor van Skijlen <sektor@spam-buffer.ald=
ec.com> pisze:
> I think better development is as that's provided as an extension
> for gcc:
>=20
> int t[3] =3D { [2] 5 };
This syntax is AFAIK deprecated. gcc now prefers the syntax defined
by C99:
int t[3] =3D { [2] =3D 5 };
You can also write a designator of the form .fieldname or even combined:
struct point ptarray[10] =3D { [2].y =3D yv2, [2].x =3D xv2, [0].x =3D=
xv0 };
All this is C99, so I would expect a future C++ standard to consider it.
--=20
__("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZAST=CAPCZA
QRCZAK
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: hstein@airmail.net (Harry Stein)
Date: Wed, 19 Sep 2001 16:38:31 GMT Raw View
Proposal for "automatic enum"
Many times I initialize an array and wish to refer to the array
indices with an "automatic enum". An automatic enum is one where you
can specify the enumerated index names without specifying a separate,
untyped, enum.
That is, suppose I have:
enum MsgTypes { information, warning, error, severe_error};
and elsewhere I have:
char *g_szMsgTypes[] =
{
"Information",
"Warning",
"Normal error",
"Severe error"
};
Often the enum and initializers are in separate files. To maintain
and extend this data structure, you would have to update the MsgTypes
enum and g_szMsgTypes array.
Pitfalls of this are obvious. Suppose one adds several new MsgTypes
but gets the g_szMsgTypes size wrong:
enum MsgTypes { new1, information, warning, error, severe_error,
new2, new3};
and elsewhere I have:
char *g_szMsgTypes[] =
{
"Information",
"Warning",
"New 1 in wrong place",
"Normal error",
"Severe error",
"new2" // forgot "new3" watch out for g_szMsgTypes[new3] ref!
};
What I would like to see is an "automatic enum". Here is some
off-the-cuff syntax:
char *g_szMsgTypes[] =
{
#Information, "Information",
#Warning, "Warning",
#New1, "Doesn't matter where we put this",
#NormalError, "Normal error",
#Severe, "Severe error",
#New2, "new2",
#New3, "new3"
} ;
Automatically generates (at the point of compilation):
enum {
Information, Warning, New1,
NormalError, Severe, New2,
New3 };
Notes:
1. #foo says add foo to an untyped enumeration and give it a value
associated with the index know at allocation time (e.g., New1 has the
value 2.
2. Don't allow #Information=expression flexibility that enum has. The
intended use of #foo is for an array index, at a fixed location.
3. The #foo can appear any number of times int the initializer list
but it cannot be repeated in the initializer list and must appear
before each indexable initializer:
char *g_szMsgTypes[] =
{
"Information:don't need enum index",
#Warning, "Warning:DO NEED enum index",
"Doesn't matter where we put this:don't need enum
index",
#Error, "Normal error:DO NEED enum index"
};
automatically generates the untyped "automatic" enum {Warning=1,
Error=3};
4. If you must use the same enumerations for multiple declarations,
the compiler will allow it so long as the values don't change:
char *g_szMsgTypes[] =
{
#Info "Information",
#Warning, "Warning:
}
char *g_SecondArray[] =
{
#Info "Take note", // okay since prev defined as 0
#Warning, "Watch it folks!" // okay since prev defined as 1
}
char *g_ThirdArray[] =
{
#Warning, "Watch it folks!" // ***error*** =0 but =1 elsewhere
#Info "Take note", // ***error*** =1 but =0 elsewhere
}
5. Multi-dimensional arrays can do this but only for the first
dimension (undoubtedly, it could be argued this would be useful for
all dimensions -- just trying to make this simpler -- let's give
ourselves a nice inch and let a few scream for miles given they never
ever had the inch :-)).
int gNumbers[3][5] =
{
#top, {11,22,33,44,55},
#middle,{22,33,44,55,66},
#bottom,{33,44,55,66,77}
}; // auto-gen: enum {top, middle, bottom};
6. Yes (and regrettably), the automatic enum is untyped. Since
language purists would correctly argue that you can't easily associate
a type with just the specific array declared, just associate the
automatic enum with the same type the standard would call for when you
have an untyped enum (I think that's an implementation-dependent
integral type such as int, short, byte, etc. -- can't recall and my
ARM is not within reach).
7. Disadvantage: untyped :-(.
8 Disadvantage: not easily accessible in header file if used in say
an implementation file. Yet, it's intended use for array indexing
which is done in code and typically in an implementation file.
But if, say, you had some inline code in a header file which wished to
use the enumerated index that had been "automatically" created, how
would you get a hold of it when the array was initialized in an
implementation file (without resorting to conditionally compiling it
if it were placed inside the header file [to avoid linker errors
associated with various implementations of the "common" model])? A
small price to pay.
9. Advantage: eliminates errors and source of maintenance errors for a
widely practiced programming style. My current practice is to have a
runtime ASSERT check:
enum(info, error, warning, ... arraysize}
char *g[] = {"aaa", "bbb"};
.
.
ASSERT( (sizeof(g)/sizeof(g[0]) == arraysize) // will assert!
10. IMHO, advantages outweigh disadvantages (spoken from many years of
experience). This makes it practical, if not perfect! Sometimes we
need practical over imperfection, especially if it saves time and
money and makes a program more readable and more maintainable.
Regards,
Harry Stein
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Sektor van Skijlen <sektor@spam-buffer.aldec.com>
Date: Wed, 19 Sep 2001 23:17:39 GMT Raw View
Dnia Wed, 19 Sep 2001 16:38:31 GMT, Harry Stein skrobe:
|What I would like to see is an "automatic enum". Here is some
|off-the-cuff syntax:
| char *g_szMsgTypes[] =
| {
| #Information, "Information",
| #Warning, "Warning",
| #New1, "Doesn't matter where we put this",
| #NormalError, "Normal error",
| #Severe, "Severe error",
| #New2, "new2",
| #New3, "new3"
|} ;
|Automatically generates (at the point of compilation):
| enum {
| Information, Warning, New1,
| NormalError, Severe, New2,
| New3 };
I don't think it's a good syntax. Besides, a user should have a possibility to
name an enum type,. I think better development is as that's provided as an
extension for gcc:
int t[3] = { [2] 5 };
that's equivalent to:
= { 0, 0, 5, 0 };
There could be used (probably, because I don't have a version of gcc which
implements this extension; documentation says, that it's not supported for
C++, but I see that 2.95.2 version does not support it at all) in such a way:
const char* names [] = {
[Information] "Information",
[Warning] "Warning,
};
and so on. Of course, you should first provide a defined enumeration type,
e.g.:
enum eMessageTypes {
Information, Warning // ...
};
The only disadvantage in comparison with your proposition is that you must
make the change twice (in the array and in the enum labels) and there is a
possibility to make an inconsistence, when you make a new enum label and won't
assign it a string.
I think this could be nice, but now I don't see any good syntax for that.
Regards,
--
// _ ___ Michal "Sektor" Malecki <sektor(@)kis.p.lodz.pl>
\\ L_ |/ `| /^\ ,() <sektor(@)aldec.katowice.pl>
// \_ |\ \/ \_/ /\ C++ bez cholesterolu: http://www.kis.p.lodz.pl/~sektor/cbx
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Daniel Pfeffer" <daniel.pfeffer@storlogic.co.il>
Date: Thu, 20 Sep 2001 12:30:53 GMT Raw View
"Harry Stein" <hstein@airmail.net> wrote in message
news:707c5551.0109190815.5d46a335@posting.google.com...
> Proposal for "automatic enum"
>
> Many times I initialize an array and wish to refer to the array
> indices with an "automatic enum". An automatic enum is one where you
> can specify the enumerated index names without specifying a separate,
> untyped, enum.
>
> That is, suppose I have:
>
> enum MsgTypes { information, warning, error, severe_error};
>
> and elsewhere I have:
>
> char *g_szMsgTypes[] =
> {
> "Information",
> "Warning",
> "Normal error",
> "Severe error"
> };
>
> Often the enum and initializers are in separate files. To maintain
> and extend this data structure, you would have to update the MsgTypes
> enum and g_szMsgTypes array.
>
> Pitfalls of this are obvious. Suppose one adds several new MsgTypes
> but gets the g_szMsgTypes size wrong:
>
> enum MsgTypes { new1, information, warning, error, severe_error,
> new2, new3};
>
> and elsewhere I have:
>
> char *g_szMsgTypes[] =
> {
> "Information",
> "Warning",
> "New 1 in wrong place",
> "Normal error",
> "Severe error",
> "new2" // forgot "new3" watch out for g_szMsgTypes[new3] ref!
> };
>
> What I would like to see is an "automatic enum". Here is some
> off-the-cuff syntax:
>
> char *g_szMsgTypes[] =
> {
> #Information, "Information",
> #Warning, "Warning",
> #New1, "Doesn't matter where we put this",
> #NormalError, "Normal error",
> #Severe, "Severe error",
> #New2, "new2",
> #New3, "new3"
> } ;
>
A better idea, borrowed from Pascal, would be something like this:
enum MsgTypes {information, warning, error, severe_error};
char *g_szMsgTypes[MsgTypes] = {
...
};
This would declare the array to have as many elements as the enum has
members. Elements not given explicit values would be initialised using the
default constructor, while too many initialisers would cause a diagnostic.
--
Daniel Pfeffer
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: tinct@163.com (Tinct)
Date: Thu, 20 Sep 2001 12:31:25 GMT Raw View
I love the extension for gcc like below,
struct stype {
int first;
char * second;
double third;
};
stype s = { second: "Hello", first: 10};
> I don't think it's a good syntax. Besides, a user should have a possibility to
> name an enum type,. I think better development is as that's provided as an
> extension for gcc:
>
> int t[3] = { [2] 5 };
>
> that's equivalent to:
>
> = { 0, 0, 5, 0 };
>
> There could be used (probably, because I don't have a version of gcc which
> implements this extension; documentation says, that it's not supported for
> C++, but I see that 2.95.2 version does not support it at all) in such a way:
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]