Enumerators, Templates, and Type Safety

Discussion in 'C++' started by Matt Taylor, Jul 2, 2004.

  1. Matt Taylor

    Matt Taylor Guest

    I'm trying to write an x86 assembler in C++ for use in a debugger. What I'd
    like do is to use template specialization to prevent invalid combinations
    from compiling. Thus one could not accidentally add a 16-bit register and an
    8-bit register since there is no encoding for this on the x86 architecture.

    My trouble has stemmed from the fact that enumerators are only integers and
    can be freely cast into other enumerators, and I was using them to attempt
    type safety. I declared REG8, REG16, and REG32 enumerated types, but the
    compiler will implicitly cast between them. So, my question is: is there any
    way to create 3 distinct types that I can use in template specialization to
    enforce assembler operand restrictions at compile-time?

    -Matt
    Matt Taylor, Jul 2, 2004
    #1
    1. Advertising

  2. Matt Taylor wrote:
    > I'm trying to write an x86 assembler in C++ for use in a debugger. What I'd
    > like do is to use template specialization to prevent invalid combinations
    > from compiling. Thus one could not accidentally add a 16-bit register and an
    > 8-bit register since there is no encoding for this on the x86 architecture.
    >
    > My trouble has stemmed from the fact that enumerators are only integers and
    > can be freely cast into other enumerators, and I was using them to attempt
    > type safety. I declared REG8, REG16, and REG32 enumerated types, but the
    > compiler will implicitly cast between them. So, my question is: is there any
    > way to create 3 distinct types that I can use in template specialization to
    > enforce assembler operand restrictions at compile-time?


    How about

    class REG8 {} AL,AH,BL,BH,CL,CH,DL,DH;
    class REG16 {} AX,BX,CX,DX,SI,DI,BP,SP,IP;
    class REG32 {} EAX ...

    Now you have types, you have objects. You can't easily use them
    in a 'switch', but do you care? There is no conversion between
    any of them, and you can specialise your templates based on them
    as much as you can specialise any templates.

    V
    Victor Bazarov, Jul 2, 2004
    #2
    1. Advertising

  3. Matt Taylor

    JKop Guest

    Victor Bazarov posted:

    > Matt Taylor wrote:
    >> I'm trying to write an x86 assembler in C++ for use in a debugger.
    >> What I'd like do is to use template specialization to prevent invalid
    >> combinations from compiling. Thus one could not accidentally add a
    >> 16-bit register and an 8-bit register since there is no encoding for
    >> this on the x86 architecture.
    >>
    >> My trouble has stemmed from the fact that enumerators are only
    >> integers and can be freely cast into other enumerators, and I was
    >> using them to attempt type safety. I declared REG8, REG16, and REG32
    >> enumerated types, but the compiler will implicitly cast between them.
    >> So, my question is: is there any way to create 3 distinct types that I
    >> can use in template specialization to enforce assembler operand
    >> restrictions at compile-time?

    >
    > How about
    >
    > class REG8 {} AL,AH,BL,BH,CL,CH,DL,DH;
    > class REG16 {} AX,BX,CX,DX,SI,DI,BP,SP,IP;
    > class REG32 {} EAX ...
    >
    > Now you have types, you have objects. You can't easily use them
    > in a 'switch', but do you care? There is no conversion between
    > any of them, and you can specialise your templates based on them
    > as much as you can specialise any templates.
    >
    > V


    or maybe

    namespace REG8 {
    enum REG8 {

    AL,AH,BL,BH,CL,CH,DL,DH }}

    namespace REG16 {
    enum REG16 {
    AX,BX,CX,DX,SI,DI,BP,SP,IP }}


    void Add(REG16 x, REG16 y);

    void Add(REG8 x, REG8 y);


    int main()
    {
    Add(REG16::BX,REG16::BP);

    Add(REG8::BH,REG8::DH);

    Add(REG16::BX,REG8::AL); //COMPILE ERROR
    }


    -JKop
    JKop, Jul 3, 2004
    #3
  4. Matt Taylor

    JKop Guest

    JKop posted:

    > Victor Bazarov posted:
    >
    >> Matt Taylor wrote:
    >>> I'm trying to write an x86 assembler in C++ for use in a debugger.
    >>> What I'd like do is to use template specialization to prevent invalid
    >>> combinations from compiling. Thus one could not accidentally add a
    >>> 16-bit register and an 8-bit register since there is no encoding for
    >>> this on the x86 architecture.
    >>>
    >>> My trouble has stemmed from the fact that enumerators are only
    >>> integers and can be freely cast into other enumerators, and I was
    >>> using them to attempt type safety. I declared REG8, REG16, and REG32
    >>> enumerated types, but the compiler will implicitly cast between them.
    >>> So, my question is: is there any way to create 3 distinct types that I
    >>> can use in template specialization to enforce assembler operand
    >>> restrictions at compile-time?

    >>
    >> How about
    >>
    >> class REG8 {} AL,AH,BL,BH,CL,CH,DL,DH;
    >> class REG16 {} AX,BX,CX,DX,SI,DI,BP,SP,IP;
    >> class REG32 {} EAX ...
    >>
    >> Now you have types, you have objects. You can't easily use them
    >> in a 'switch', but do you care? There is no conversion between
    >> any of them, and you can specialise your templates based on them
    >> as much as you can specialise any templates.
    >>
    >> V

    >
    > or maybe
    >
    > namespace REG8 {
    > enum REG8 {
    >
    > AL,AH,BL,BH,CL,CH,DL,DH }}
    >
    > namespace REG16 {
    > enum REG16 {
    > AX,BX,CX,DX,SI,DI,BP,SP,IP }}
    >
    >
    > void Add(REG16 x, REG16 y);
    >
    > void Add(REG8 x, REG8 y);


    Opps!

    void Add(REG16::REG16 x, REG16::REG16 y);

    void Add(REG8::REG8 x, REG8::REG8 y);

    -JKop
    JKop, Jul 3, 2004
    #4
  5. Matt Taylor

    Matt Taylor Guest

    "JKop" <> wrote in message
    news:5fvFc.3745$...
    > Victor Bazarov posted:
    >
    > > Matt Taylor wrote:
    > >> I'm trying to write an x86 assembler in C++ for use in a debugger.
    > >> What I'd like do is to use template specialization to prevent invalid
    > >> combinations from compiling. Thus one could not accidentally add a
    > >> 16-bit register and an 8-bit register since there is no encoding for
    > >> this on the x86 architecture.
    > >>
    > >> My trouble has stemmed from the fact that enumerators are only
    > >> integers and can be freely cast into other enumerators, and I was
    > >> using them to attempt type safety. I declared REG8, REG16, and REG32
    > >> enumerated types, but the compiler will implicitly cast between them.
    > >> So, my question is: is there any way to create 3 distinct types that I
    > >> can use in template specialization to enforce assembler operand
    > >> restrictions at compile-time?

    > >
    > > How about
    > >
    > > class REG8 {} AL,AH,BL,BH,CL,CH,DL,DH;
    > > class REG16 {} AX,BX,CX,DX,SI,DI,BP,SP,IP;
    > > class REG32 {} EAX ...
    > >
    > > Now you have types, you have objects. You can't easily use them
    > > in a 'switch', but do you care? There is no conversion between
    > > any of them, and you can specialise your templates based on them
    > > as much as you can specialise any templates.
    > >
    > > V

    >
    > or maybe
    >
    > namespace REG8 {
    > enum REG8 {
    >
    > AL,AH,BL,BH,CL,CH,DL,DH }}
    >
    > namespace REG16 {
    > enum REG16 {
    > AX,BX,CX,DX,SI,DI,BP,SP,IP }}
    >
    >
    > void Add(REG16 x, REG16 y);
    >
    > void Add(REG8 x, REG8 y);
    >
    >
    > int main()
    > {
    > Add(REG16::BX,REG16::BP);
    >
    > Add(REG8::BH,REG8::DH);
    >
    > Add(REG16::BX,REG8::AL); //COMPILE ERROR
    > }


    What about template specialization, e.g. Add<REG16::BX, REG8::AL>()? I
    suppose I can live with passing parameters, but I'd hoped to use
    specialization to force the compiler to inline everything.

    -Matt
    Matt Taylor, Jul 7, 2004
    #5
  6. Matt Taylor

    Matt Taylor Guest

    "Victor Bazarov" <> wrote in message
    news:vojFc.1491$...
    > Matt Taylor wrote:
    > > I'm trying to write an x86 assembler in C++ for use in a debugger. What

    I'd
    > > like do is to use template specialization to prevent invalid

    combinations
    > > from compiling. Thus one could not accidentally add a 16-bit register

    and an
    > > 8-bit register since there is no encoding for this on the x86

    architecture.
    > >
    > > My trouble has stemmed from the fact that enumerators are only integers

    and
    > > can be freely cast into other enumerators, and I was using them to

    attempt
    > > type safety. I declared REG8, REG16, and REG32 enumerated types, but the
    > > compiler will implicitly cast between them. So, my question is: is there

    any
    > > way to create 3 distinct types that I can use in template specialization

    to
    > > enforce assembler operand restrictions at compile-time?

    >
    > How about
    >
    > class REG8 {} AL,AH,BL,BH,CL,CH,DL,DH;
    > class REG16 {} AX,BX,CX,DX,SI,DI,BP,SP,IP;
    > class REG32 {} EAX ...
    >
    > Now you have types, you have objects. You can't easily use them
    > in a 'switch', but do you care? There is no conversion between
    > any of them, and you can specialise your templates based on them
    > as much as you can specialise any templates.


    This seems to work pretty well. I actually ended up creating a generic class
    that represents each register type, i.e. REG8, REG16, and REG32. They are
    templated with an integer, i.e. EAX = REG32<0>. Now I can use partial
    specialization to easily select between register types. Thanks!

    -Matt
    Matt Taylor, Jul 13, 2004
    #6
  7. Matt Taylor wrote:
    > "Victor Bazarov" <> wrote in message
    > news:vojFc.1491$...
    >
    >>[...]

    > [..] I actually ended up creating a generic class
    > that represents each register type, i.e. REG8, REG16, and REG32. They are
    > templated with an integer, i.e. EAX = REG32<0>. Now I can use partial
    > specialization to easily select between register types. Thanks!


    It's very gratifying to interact with somebody who understands what
    you're talking about and uses it successfully. Thank you. -- V
    Victor Bazarov, Jul 13, 2004
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    6
    Views:
    4,165
    Pete Becker
    Apr 23, 2005
  2. Dave
    Replies:
    1
    Views:
    316
    Ron Natalie
    Nov 9, 2005
  3. Replies:
    5
    Views:
    112
  4. Omran Nazir

    Newbie question: Enumerators

    Omran Nazir, Nov 21, 2009, in forum: Ruby
    Replies:
    4
    Views:
    135
    Omran Nazir
    Nov 22, 2009
  5. Hal Fulton

    Enumerators and generators

    Hal Fulton, Jul 22, 2010, in forum: Ruby
    Replies:
    7
    Views:
    123
    Roger Pack
    Jul 22, 2010
Loading...

Share This Page