468,754 Members | 1,417 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,754 developers. It's quick & easy.

Enumerators, Templates, and Type Safety

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
Jul 22 '05 #1
6 1666
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
Jul 22 '05 #2
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
Jul 22 '05 #3
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
Jul 22 '05 #4
"JKop" <NU**@NULL.NULL> wrote in message
news:5f*****************@news.indigo.ie...
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
Jul 22 '05 #5
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:vo****************@ord-read.news.verio.net...
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
Jul 22 '05 #6
Matt Taylor wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:vo****************@ord-read.news.verio.net...
[...]

[..] 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
Jul 22 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by kelvSYC | last post: by
18 posts views Thread by aarklon | last post: by
11 posts views Thread by San | last post: by
23 posts views Thread by Ben Voigt | last post: by
104 posts views Thread by JohnQ | last post: by
21 posts views Thread by Chad | last post: by
muaddubby
1 post views Thread by muaddubby | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.