Topic: String representations of enum members


Author: =?ISO-8859-1?Q?J=F6rg?= Barfurth <joerg.barfurth@germany.sun.com>
Date: 2000/04/26
Raw View
Am 25.04.00, 00:31:53, schrieb AllanW <allan_w@my-deja.com> zum Thema Re:=
=20
String representations of enum members:


> joerg.barfurth@germany.sun.com wrote:
> > So we'll probably have to stick to macros to support i/o or display
> > for enums.

> These are all reasons why the programmer can know what "the obvious
> thing" is but the compiler can't. But they are NOT reasons to use
> macros!

[SNIP some]
>     const char*enumid(Quality x) {
>         switch (x) {
>         case lowestQuality:    return "Quality::lowestQuality";
>         case highestQuality:   return "Quality::highestQuality";
>         default: {
>             const char*z =3D enumBuffer();
>             sprintf(z, "Quality::(%ld%s)",long(x),
>                 (x<lowestQuality || x>highestQuality)
>                     ? "(Invalid)" : "");
>             return z;
>             }
>         }
>     }
[.. and some more]

> This avoids the use of macros. Naturally, you might prefer to
> use some other algorithms, especially to avoid using
> enumBuffer() (the weak point in the version I've shown here).
> But the algorithm isn't my point.

> Writing your own enumid() might not be as convenient as hoping
> that the compiler will do it for you, but it isn't all that
> difficult, either. Fortunately, it only has to be done (at
> most) once per enumeration, and we've already shown that it
> is neccesary anyway (due to the different possible meanings
> of enums).

I was not advocating spreading macros all over the program. Actually=20
(iirc) the OP suggested that macros were the way to go without having a=20
builtin enumid().=20
But yes, I have to admit that I have used macros in a similar context.=20
Not to be used in public header files, but to implement the homebrew=20
enumid versions you advocate.=20

It is more tedious and error-prone to write and maintain all those switch=
=20
cases manually than to have a macro to generate such boilerplate lines.=20
Better yet would be a tool that generates the enums declaration, the=20
enumid function and maybe a couple of streaming operators, all from the=20
same source. But if that is too much for the task on hand, macros are the=
=20
poor man's code generation tools.

-- J=F6rg Barfurth



---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: kanze@gabi-soft.de
Date: 2000/05/02
Raw View
comeau@panix.com (Greg Comeau) writes:

|>  I might be inclined to agree philosophically, but technically I'm
|>  still trying to understand the details.  For instance, consider:

|>  enum x { fe };
|>  enum y { fi };

|>  ......enumid(0)...

|>  What do you want to happen?

The same thing as what happens in:

    void f( x ) ;
    void f( y ) ;
    //  ditto for *all* declared enums in program...

    f( 0 ) ;

--=20
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh=FCttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW <allan_w@my-deja.com>
Date: 2000/04/24
Raw View
joerg.barfurth@germany.sun.com wrote:
> schrieb comeau@panix.com (Greg Comeau)
> > I might be inclined to agree philosophically, but technically I'm
> > still trying to understand the details.  For instance, consider:
>
> > enum x { fe };
> > enum y { fi };
>
> > ......enumid(0)...
>
> > What do you want to happen?
>
> I want the compiler to output a diagnostic:
>     'enumid(int): enumid requires an enumerated type'.
>
> The static type of the argument of enumid would have to be an
> enumerated type.
>
> Effectively it behaves as though we had a declaration:
>   template<enum E> char const * enumid(E);
> where (as indicated) the compiler could automagically instantiate
> that template iff E is an enumerated type.
>
> But I think this is not feasible.
> As you indicated, the enumerator associated with a value need not be
> unique:
>
>   enum Mode {
>     mode1,
>     mode2,
>     mode3,
>
>     defaultMode = mode2
>   };
>   Mode foo(Mode m = defaultMode) { return m; }
>
>   enumid( mode2 ); // ?
>   enumid( defaultMode ); // ?
>
>   enumid( foo() ); // ?
>
> A still bigger problem is, that not all values of an enumerated type
> need to have an associated enumerator:
>   enum Quality { lowestQuality = 0, highestQuality = 100 };
>   const Quality mediumQuality = Quality((lowestQuality +
> highestQuality)/2);
>
>   enumid(mediumQuality); // ?
>
> Among these cases is the use of enumerations for bitmasks:
>   enum Mask { flag1 = 001, flag2 = 002, flag3 = 004 };
>   Mask operator | (Mask l, Mask r) { return Mask(l | 0 | r); }
>
>   enumid(flag1 | flag2); // ?
>
> So we'll probably have to stick to macros to support i/o or display
> for enums.

These are all reasons why the programmer can know what "the obvious
thing" is but the compiler can't. But they are NOT reasons to use
macros!

    // This mechanism can be abused; for instance
    //     const char *enumName = enumid(xxx)
    //     function_that_calls_enumid_100_times();
    //     cout << enumName; // Now might be stale!
    // However, for most "normal" usage 80 buffers should
    // be plenty!
    namespace {
        char *enumBuffer() {
            static char buffer[80][80];
            static int nextbuff=0;
            nextbuff = (nextbuff+1) %
                (sizeof(buffer)/sizeof(buffer[0])));
            return buffer[nextbuff];
        }
    };

    const char*enumid(Mode x) {
        switch (x) {
        case mode1:    return "Mode::mode1";
        case mode2:    return "Mode::mode2(default)";
        case mode3:    return "Mode::mode3";
        default: {
            const char*z = enumBuffer();
            sprintf(z,"Mode::(%ld)",long(x));
            return z;
            }
        }
    }
    const char*enumid(Quality x) {
        switch (x) {
        case lowestQuality:    return "Quality::lowestQuality";
        case highestQuality:   return "Quality::highestQuality";
        default: {
            const char*z = enumBuffer();
            sprintf(z, "Quality::(%ld%s)",long(x),
                (x<lowestQuality || x>highestQuality)
                    ? "(Invalid)" : "");
            return z;
            }
        }
    }
    const char*enumid(Mask x) {
        switch (x) {
        case 0:        return "Quality::lowestQuality";
        case flag1:    return "Mask::flag1";
        case flag2:    return "Mask::flag2";
        case flag3:    return "Mask::flag3";
        default: {
            const char*z = enumBuffer();
            strcpy(z, "Mask::");
            if (x & flag1) strcat(z, "|flag1");
            if (x & flag2) strcat(z, "|flag2");
            if (x & flag3) strcat(z, "|flag3");
            z[6]='(';
            strcat(z,")");
            return z;
            }
        }
    }

This avoids the use of macros. Naturally, you might prefer to
use some other algorithms, especially to avoid using
enumBuffer() (the weak point in the version I've shown here).
But the algorithm isn't my point.

Writing your own enumid() might not be as convenient as hoping
that the compiler will do it for you, but it isn't all that
difficult, either. Fortunately, it only has to be done (at
most) once per enumeration, and we've already shown that it
is neccesary anyway (due to the different possible meanings
of enums).

--
Allan_W@my-deja.com is a "Spam Magnet," never read.
Please reply in newsgroups only, sorry.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jim Cobban <thesnaguy@hotmail.com>
Date: 2000/04/18
Raw View
This is a multi-part message in MIME format.
--------------A0431BD74E9939C94D8BD745
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Timur Aydin wrote:

> Quite often it is necessary to log the current value of a variable into
> either a log file, a trace buffer another storage medium in order to track
> down a problem. ...

....

> If the C++ standard could define an operator that returns the string
> representation (for instance "enumid", everything would be very easy:
>
> clog << "The state is  " << enumid(state))

There is already a similar situation to this for the bool type.  Most
programmers had defined their own BOOL type, either with #defines, or as an
enum.  When the bool type was added to C++ many programmers switched to using
it.  One of the nice features of the bool type is that there is an ios
formatting flag, boolalpha, which if it is set causes bool values to be
formatted as "true" and "false" instead of as 1 or 0.

As Timur says we have all, at one time or another, written debugging code to
dump out the symbolic meanings of enumeration values, and have used one or other
trick to keep the translation table in synch with the enumeration definition.
One of the points of standardization is to increase productivity by having the
compiler handle repetitive tasks like this.

I would therefore suggest that one implementation would be to define an
ios_base::enumalpha format flag and an enumalpha manipulator which sets that
flag for IOstreams.  If this flag is set, and if the program was compiled with
debugging data, which means that the textual values of the enumeration constants
are already present in the executeable to support the IDE's debugger, then
enumeration values would be presented as the symbolic value on ostreams.

Beyond this basic level of support there are a few possible extensions, which
are of lesser, but still significant value:

How many times has someone posted a request in the newsgroups for a way to read
a string from an istream and then do a switch on it?  The most logical
interpretation for enumalpha on an istream would be to read the next token from
the input and then match it against the textual values of the enumeration to
derive the appropriate value of the enumeration.  A big difference over the
requested support for printing enums is that this support for input would be
required in production code, as well as in debugging code, which would require
the compiler to determine for which enumerations it was necessary to include the
symbolic values.

--
Jim Cobban   jcobban@magma.ca
34 Palomino Dr.
Kanata, ON, CANADA
K2M 1M1
+1-613-592-9438


--------------A0431BD74E9939C94D8BD745
Content-Type: text/x-vcard; charset=us-ascii;
 name="thesnaguy.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Jim Cobban
Content-Disposition: attachment;
 filename="thesnaguy.vcf"

begin:vcard
n:Cobban;James
tel;fax:+1-613-592-9438
tel;home:+1-613-592-9438
x-mozilla-html:FALSE
url:http://www.magma.ca/~jcobban
version:2.1
email;internet:thesnaguy@hotmail.com
title:Consultant
adr;quoted-printable:;;34 Palomino Dr.=0D=0A;Kanata;ON;K2M 1M1;Canada
fn:Jim Cobban
end:vcard

--------------A0431BD74E9939C94D8BD745--

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Barry Margolin <barmar@genuity.net>
Date: 2000/04/19
Raw View
In article <8dfu6v$pm3$1@panix.com>,
Greg Comeau <comeau@comeaucomputing.com> wrote:
>I might be inclined to agree philosophically, but technically I'm
>still trying to understand the details.  For instance, consider:
>
>enum x { fe };
>enum y { fi };
>
>......enumid(0)...
>
>What do you want to happen?

A compiler diagnostic.  enumid((enum x)0) and enumid((enum y)0) should
work, producing "fe" and "fi", respectively.

--
Barry Margolin, barmar@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/04/19
Raw View
Greg Comeau wrote:
>
> In article <4eKK4.61$Mv3.1715@burlma1-snr2> Barry Margolin <barmar@genuity.net> writes:
> >In article <8dfpos$9o3$1@panix.com>,
> >Greg Comeau <comeau@comeaucomputing.com> wrote:
> >>In article <8de1dc$q3e$1@bob.news.rcn.net> "Timur Aydin"
> >><taydin@erols.com> writes:
> >>>clog << "The state is  " << enumid(state))
> >...
> >The compiler would be able to check that "state" is indeed declared to be
> >of an enumeration type, and otherwise wouldn't compile the code.  Once it
> >has determined that it is declared to be of type "enum STATES" it can
> >generate the appropriate translation code.
> >
> >This proposal seems pretty reasonable.  The compiler only needs to generate
> >code for the actual types that are mentioned in the arguments to enumid.
> >There's no overhead for other types, and if the translation unit doesn't
> >use enumid there's no reason for any overhead at all.  It could be pretty
> >useful for templates that are parametrized on enumerated types.
>
> I might be inclined to agree philosophically, but technically I'm
> still trying to understand the details.  For instance, consider:
>
> enum x { fe };
> enum y { fi };
>
> ......enumid(0)...
>
> What do you want to happen?

At best, that's ambiguous. However, I'd like cout << enumid((enum x)0)
to print "fe".

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: =?ISO-8859-1?Q?J=F6rg?= Barfurth <joerg.barfurth@germany.sun.com>
Date: 2000/04/19
Raw View
Am 18.04.00, 09:12:46, schrieb comeau@panix.com (Greg Comeau) zum Thema
Re: String representations of enum members:


> In article <4eKK4.61$Mv3.1715@burlma1-snr2> Barry Margolin
<barmar@genuity.net> writes:

> >>In article <8de1dc$q3e$1@bob.news.rcn.net> "Timur Aydin"<taydin@erols.com>
writes:
> >>>clog << "The state is  " << enumid(state))

> >This proposal seems pretty reasonable.  The compiler only needs to
generate
> >code for the actual types that are mentioned in the arguments to enumid.
> >There's no overhead for other types, and if the translation unit doesn't
> >use enumid there's no reason for any overhead at all.  It could be
pretty
> >useful for templates that are parametrized on enumerated types.

> I might be inclined to agree philosophically, but technically I'm
> still trying to understand the details.  For instance, consider:

> enum x { fe };
> enum y { fi };

> ......enumid(0)...

> What do you want to happen?

I want the compiler to output a diagnostic: 'enumid(int): enumid requires
an enumerated type'.

The static type of the argument of enumid would have to be an enumerated
type.

Effectively it behaves as though we had a declaration:
  template<enum E> char const * enumid(E);
where (as indicated) the compiler could automagically instantiate that
template iff E is an enumerated type.

But I think this is not feasible.
As you indicated, the enumerator associated with a value need not be
unique:

  enum Mode {
    mode1,
    mode2,
    mode3,

    defaultMode = mode2
  };
  Mode foo(Mode m = defaultMode) { return m; }

  enumid( mode2 ); // ?
  enumid( defaultMode ); // ?

  enumid( foo() ); // ?

A still bigger problem is, that not all values of an enumerated type need
to have an associated enumerator:
  enum Quality { lowestQuality = 0, highestQuality = 100 };
  const Quality mediumQuality = Quality((lowestQuality +
highestQuality)/2);

  enumid(mediumQuality); // ?

Among these cases is the use of enumerations for bitmasks:
  enum Mask { flag1 = 001, flag2 = 002, flag3 = 004 };
  Mask operator | (Mask l, Mask r) { return Mask(l | 0 | r); }

  enumid(flag1 | flag2); // ?

So we'll probably have to stick to macros to support i/o or display for
enums.

-- J   rg Barfurth




---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Barry Margolin <barmar@genuity.net>
Date: 2000/04/19
Raw View
In article <20000418.8022058@jb-11116.stardiv.de>,
J   rg Barfurth  <joerg.barfurth@germany.sun.com> wrote:
>But I think this is not feasible.
>As you indicated, the enumerator associated with a value need not be
>unique:
>
>  enum Mode {
>    mode1,
>    mode2,
>    mode3,
>
>    defaultMode = mode2
>  };
>  Mode foo(Mode m = defaultMode) { return m; }
>
>  enumid( mode2 ); // ?
>
>  enumid( defaultMode ); // ?


We could simply define that enumid() should return the label that appears
lexically first in the declaration, so they should both return "mode2".

>  enumid( foo() ); // ?
>
>A still bigger problem is, that not all values of an enumerated type need
>to have an associated enumerator:
>  enum Quality { lowestQuality = 0, highestQuality = 100 };
>  const Quality mediumQuality = Quality((lowestQuality +
>highestQuality)/2);
>
>  enumid(mediumQuality); // ?

How about returning "lowestQuality+50"?  It would find the closest
enumerator below the value, and return that label plus an offset; if the
value is less then the smallest enumerator, it would use a negative offset
from that.  This is reminiscent of how assembly language debuggers display
memory locations that don't correspond exactly to labels.

>Among these cases is the use of enumerations for bitmasks:
>  enum Mask { flag1 = 001, flag2 = 002, flag3 = 004 };
>  Mask operator | (Mask l, Mask r) { return Mask(l | 0 | r); }
>
>  enumid(flag1 | flag2); // ?
>
>So we'll probably have to stick to macros to support i/o or display for
>enums.

Based on my above recommendation, it would return "flag2+1".  This isn't
what you would really like to see, but that just means that enumid() isn't
useful for bitmasks.  Just because it doesn't handle some situations
doesn't mean it isn't useful.

--
Barry Margolin, barmar@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Martijn Lievaart" <news-from@greebo.orion.nl>
Date: 2000/04/19
Raw View
"Greg Comeau" <comeau@panix.com> wrote in message
news:8dfu6v$pm3$1@panix.com...
> In article <4eKK4.61$Mv3.1715@burlma1-snr2> Barry Margolin
<barmar@genuity.net> writes:
> >In article <8dfpos$9o3$1@panix.com>,
> >Greg Comeau <comeau@comeaucomputing.com> wrote:
> >>In article <8de1dc$q3e$1@bob.news.rcn.net> "Timur Aydin"
> >><taydin@erols.com> writes:
> >>>clog << "The state is  " << enumid(state))
> >...
> >The compiler would be able to check that "state" is indeed declared to be
> >of an enumeration type, and otherwise wouldn't compile the code.  Once it
> >has determined that it is declared to be of type "enum STATES" it can
> >generate the appropriate translation code.
> >
> >This proposal seems pretty reasonable.  The compiler only needs to
generate
> >code for the actual types that are mentioned in the arguments to enumid.
> >There's no overhead for other types, and if the translation unit doesn't
> >use enumid there's no reason for any overhead at all.  It could be pretty
> >useful for templates that are parametrized on enumerated types.
>
> I might be inclined to agree philosophically, but technically I'm
> still trying to understand the details.  For instance, consider:
>
> enum x { fe };
> enum y { fi };
>
> ......enumid(0)...
>
> What do you want to happen?
>

Not an enum => won't compile.

......enumid(x(0))...

would compile.

HTH,
M4
--
Contrary to popular believe, the number of the beast is not 666,
it's 555-37689.
Please post replies to this newsgroup. If you must reach
me by email, use <newsgroup-name> at greebo.orion in nl.



---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Dennis Yelle <dennis51@jps.net>
Date: 2000/04/19
Raw View
Timur Aydin wrote:
[...]
> enum STATES
> {
>   L_evt_init = 0,
>   L_evt_waitdata,
>   L_evt_senddata,
>   L_evt_waitack,
>    *
>    *
>    *
> };

STATES state;

....

> clog << "The state is  " << enumid(state))

I think that this would be better:

  clog << "The state is " << state.c_str();

Dennis Yelle

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Hyman Rosen <hymie@prolifics.com>
Date: 2000/04/20
Raw View
=?ISO-8859-1?Q?J=F6rg?= Barfurth <joerg.barfurth@germany.sun.com> writes:
> So we'll probably have to stick to macros to support i/o or display for
> enums.

No need to give up so quickly! Let's have something like the following:

namespace std
{
 template <typename T>
 struct image_s { static string get_image(const T &); };
 template <typename T>
 string image(const T &value) { return image_s<T>::get_image(value); }
}

We define that for enumerations, get_image returns the stringized form
of the first enumeration literal of that type which matches the given
value, and otherwise have the result be undefined, implementation
defined, or defined as something specific, according to taste. If we
get very ambitious, we can also define behavior for basic types other
than enumerations, and maybe allow specialization of image_s for
user-defined types.

For actual standardization, we would further templatize on character
type to get narrow and wide forms of image.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Timur Aydin" <taydin@erols.com>
Date: 2000/04/18
Raw View
Hi,

Quite often it is necessary to log the current value of a variable into
either a log file, a trace buffer another storage medium in order to track
down a problem. This is especially useful with multithreaded application.
Suppose the variable in question is of an enumeration type:

enum STATES
{
  L_evt_init = 0,
  L_evt_waitdata,
  L_evt_senddata,
  L_evt_waitack,
   *
   *
   *
};

When logging the current value of this variable, it is very desirable to log
"L_evt_init" instead of 0, "L_evt_senddata" instead of 2. It is certainly
possible to write code that does this, however:

1. A separate function would be needed for each enum, because different sets
might have different literal with the same integral value.

2. It is easy to make a mistake which would result in the wrong string to be
returned for a given enum member.

3. Too much effort is required. Defining the string tables, writing the
lookop code and doing range checking.

If the C++ standard could define an operator that returns the string
representation (for instance "enumid", everything would be very easy:

clog << "The state is  " << enumid(state))

The compiler would be able to check that "state" is indeed of type "enum
STATES" and otherwise wouldn't compile the code. The compiler would also
have the string representation of each enum member in its internal symbol
table. The only thing the compiler needs to do is to insert a string table
and a short piece of code that does the lookup. If the integer is out of
range, an empty string would be returned.

I think this would help reducing the number of bugs in large programs that
make use of enumerations.

Anybody else feel the same way?

Timur.


---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: comeau@panix.com (Greg Comeau)
Date: 2000/04/18
Raw View
In article <8de1dc$q3e$1@bob.news.rcn.net> "Timur Aydin" <taydin@erols.com> writes:
>Quite often it is necessary to log the current value of a variable into
>either a log file, a trace buffer another storage medium in order to track
>down a problem. This is especially useful with multithreaded application.
>Suppose the variable in question is of an enumeration type:
>
>enum STATES {
>  L_evt_init = 0,
>  L_evt_waitdata,
>  L_evt_senddata,
>  L_evt_waitack, [...]
>};
>
>When logging the current value of this variable, it is very desirable to log
>"L_evt_init" instead of 0, "L_evt_senddata" instead of 2. It is certainly
>possible to write code that does this, however:
>
>1. A separate function would be needed for each enum, because different sets
>might have different literal with the same integral value.

Assuming only the enumerator was stored, yes, it would need to be one per.

>2. It is easy to make a mistake which would result in the wrong string to be
>returned for a given enum member.
>
>3. Too much effort is required. Defining the string tables, writing the
>lookop code and doing range checking.

Probably you could get 1/2 way with some preprocessor #arg tricks,
and probably even all the way with an awk or perl script.

>If the C++ standard could define an operator that returns the string
>representation (for instance "enumid", everything would be very easy:
>
>clog << "The state is  " << enumid(state))
>
>The compiler would be able to check that "state" is indeed of type "enum
>STATES" and otherwise wouldn't compile the code.

Why would it assume that state was from enum STATES?

>The compiler would also
>have the string representation of each enum member in its internal symbol
>table. The only thing the compiler needs to do is to insert a string table
>and a short piece of code that does the lookup. If the integer is out of
>range, an empty string would be returned.

Yes, it's there in the compiler (you could always contact a vendor
about such a extension (hint, hint :} )).

>I think this would help reducing the number of bugs in large programs that
>make use of enumerations.
>
>Anybody else feel the same way?

I can't say I've never wanted it, but I'm not sold on that being
sufficient to get it :)

- Greg
--
Comeau Computing, Producers of Comeau C/C++ 4.2.42 (4.2.43 BETA starting)
Try Comeau C++ online at http://www.comeaucomputing.com/tryitout
Email: comeau@comeaucomputing.com / WEB: http://www.comeaucomputing.com

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Barry Margolin <barmar@genuity.net>
Date: 2000/04/18
Raw View
In article <8dfpos$9o3$1@panix.com>,
Greg Comeau <comeau@comeaucomputing.com> wrote:
>In article <8de1dc$q3e$1@bob.news.rcn.net> "Timur Aydin"
><taydin@erols.com> writes:
>>If the C++ standard could define an operator that returns the string
>>representation (for instance "enumid", everything would be very easy:
>>
>>clog << "The state is  " << enumid(state))
>>
>>The compiler would be able to check that "state" is indeed of type "enum
>>STATES" and otherwise wouldn't compile the code.
>
>Why would it assume that state was from enum STATES?

What I think he actually meant to say was:

The compiler would be able to check that "state" is indeed declared to be
of an enumeration type, and otherwise wouldn't compile the code.  Once it
has determined that it is declared to be of type "enum STATES" it can
generate the appropriate translation code.

This proposal seems pretty reasonable.  The compiler only needs to generate
code for the actual types that are mentioned in the arguments to enumid.
There's no overhead for other types, and if the translation unit doesn't
use enumid there's no reason for any overhead at all.  It could be pretty
useful for templates that are parametrized on enumerated types.

--
Barry Margolin, barmar@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: comeau@panix.com (Greg Comeau)
Date: 2000/04/18
Raw View
In article <4eKK4.61$Mv3.1715@burlma1-snr2> Barry Margolin <barmar@genuity.net> writes:
>In article <8dfpos$9o3$1@panix.com>,
>Greg Comeau <comeau@comeaucomputing.com> wrote:
>>In article <8de1dc$q3e$1@bob.news.rcn.net> "Timur Aydin"
>><taydin@erols.com> writes:
>>>clog << "The state is  " << enumid(state))
>...
>The compiler would be able to check that "state" is indeed declared to be
>of an enumeration type, and otherwise wouldn't compile the code.  Once it
>has determined that it is declared to be of type "enum STATES" it can
>generate the appropriate translation code.
>
>This proposal seems pretty reasonable.  The compiler only needs to generate
>code for the actual types that are mentioned in the arguments to enumid.
>There's no overhead for other types, and if the translation unit doesn't
>use enumid there's no reason for any overhead at all.  It could be pretty
>useful for templates that are parametrized on enumerated types.

I might be inclined to agree philosophically, but technically I'm
still trying to understand the details.  For instance, consider:

enum x { fe };
enum y { fi };

......enumid(0)...

What do you want to happen?

- Greg
--
Comeau Computing, Producers of Comeau C/C++ 4.2.42 (4.2.43 BETA starting)
Try Comeau C++ online at http://www.comeaucomputing.com/tryitout
Email: comeau@comeaucomputing.com / WEB: http://www.comeaucomputing.com

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Dennis Yelle <dennis51@jps.net>
Date: 2000/04/18
Raw View
Timur Aydin proposes enumid(state) for any variable state that is an enum:
[...]
> If the C++ standard could define an operator that returns the string
> representation (for instance "enumid", everything would be very easy:
>
> clog << "The state is  " << enumid(state))
[...]
> I think this would help reducing the number of bugs in large programs that
> make use of enumerations.

Yes.

Something like this is overdue.

Dennis Yelle

---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]