Conversiion from C code to C++ code

I am trying to convert a project from C to C++. Since it is not completely written by me, I am facing some problem doing that. I know C++ enforces stricter type conversion rules, but I am facing problem a part of the code which is complaining about the conversion. I am bit confused as to how to rectify that. Can anyone please guide me in this regard?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
enum md_fu_class {
  FUClass_NA = 0,   /* inst does not use a functional unit */
  IntALU,       /* integer ALU */
  IntMULT,      /* integer multiplier */
  IntDIV,       /* integer divider */
  FloatADD,     /* floating point adder/subtractor */
  FloatCMP,     /* floating point comparator */
  FloatCVT,     /* floating point<->integer converter */
  FloatMULT,        /* floating point multiplier */
  FloatDIV,     /* floating point divider */
  FloatSQRT,        /* floating point square root */
  RdPort,       /* memory read port */
  WrPort,       /* memory write port */
  NUM_FU_CLASSES    /* total functional unit classes */
};

/* enum md_opcode -> opcode operand format, used by disassembler */           
char *md_op2format[OP_MAX] = {                                                
  NULL, /* NA */
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) OPFORM,          
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT) NULL,                                 
#define CONNECT(OP)
#include "machine.def"                                                        
};                                                                            

/* enum md_opcode -> enum md_fu_class, used by performance simulators */      
enum md_fu_class md_op2fu[OP_MAX] = {                                         
  FUClass_NA, /* NA */
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) RES,             
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT) FUClass_NA,                           
#define CONNECT(OP)
#include "machine.def"                                                        
};


Above is the code, compiler gives an error message with the third enum md_fu_class;

error: invalid conversion from ‘int’ to ‘md_fu_class’

How do I resolve it?

Thanks in advance
You'll need to cast it. If you're still not sure what to do, can you post the code with the error.

The treatment enums is one of the few areas where C and C++ differ. In C, and enum is always an int. In C++ it can (but often doesn't) vary in size.

Be carefull with the cast, your information might be effected/corrupt if it does not fit into allocated space for
md_fu_class md_op2fu[OP_MAX]


if you are confident with the data part then go ahead and use explicit casts.

kbw is right what all are elements of enum / defined states of the enum , the enumeration variable can take in those defined states only. (size ~ int type in memory)


Thanks for you valuable insights..... But still I am not sure how to typecast and what to typecast? I could have posted the code, but its huge. and I have already posted the relevant part of it. :S
Just post one instance of a relevant line. I'm sure you'll have plenty of instances.
I tried using those casting techniques in the link given by Zhuge.... but still I can't make it work. Is there a way to upload the files?

Thanks once again..
I have uploaded it on my webpage....

www.cse.iitk.ac.in/users/rachitag/codes.tar.gz

if someone can give me some pointers... i will really be grateful.... Thanks in advance
I won't download your whole program/project.

Can you just post the line that's causing the error.
In my first post, line num 28 is causing the problem:

It says

invalid conversion from ‘int’ to ‘md_fu_class’


Thanks
Actually the problem is I am not getting how files are included in the enum declaration and what does it exactly mean by having array of enums.....
Thanks
your file "machine.def" contains definitions (most probably in the form of using the #defines above the include) that declare integer variables instead of symbols taken from md_fu_class.

You have to trac them down in machine.def and either put a cast to md_fu_class before them (could be possible that the cast is needed in the #defines in lines 29 to 31) or you use the symbol from the md_fu_class enum instead.

The problem here is that in C++ an enum defines a new type and any plain integer can not be converted to this new type (converting from enum to int is possible, though). In C, all enums are just plain boring integer.

1
2
3
enum foobar { foo, bar };
...
foobar f = 1; // won't compile in C++ (but does fine in C) 


So after preprocessor resolving, your enum declaration in line 27+ probably looks something like:

1
2
3
4
5
6
enum md_fu_class md_op2fu[OP_MAX] = {                                         
  FUClass_NA, /* NA */
  1,
  2,
  3,
  ...

If you can change this to generate something like this, it would work:
1
2
3
4
5
6
enum md_fu_class md_op2fu[OP_MAX] = {                                         
  FUClass_NA, /* NA */
  (md_fu_class)1,
  (md_fu_class)2,
  (md_fu_class)3,
  ...




Note that many compiler have an option to spit out the code after preprocessor but before compiling. This could give you a nice hint where the problem is in all those defines.. ;). (IIRC, in gcc it is "-e"?)

Ciao, Imi.
Thanks for the reply. That was really helpful. Now I see where the problem is?

But still, machine.def contains some 3000 definitions and manually typecasting each of those definitions is bit difficult to do. Is there any better method to do that?

Thanks
Heck, I never would suggest to manually change all the definitions in machine.def! :-D. I meant you have to find the place where they are resolved to the integer constant that gets inserted into the md_op2fu array. There is probably like one to three places to do this.

The result could, for example look like that you have to insert the cast into the defines somehow, say.. before the first OP - parameter. (I choosen this just because this looks so suspicious and occurs in all three defines. It's most probably something else).

1
2
3
#define DEFINST( (md_fu_class)OP, MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) RES,             
#define DEFLINK( (md_fu_class)OP, MSK,NAME,MASK,SHIFT) FUClass_NA,                           
#define CONNECT( (md_fu_class)OP ) 



If nothing helps, you can always throw the nuke and convert the enum md_fu_class into a row of "static const int" statements and define md_fu_class to int. Not the uber-solution, but sometimes a man has to do, what a man has to do (and this may be doing something else than fixing every problem "the right way(tm)" ;-)

1
2
3
4
5
6
// don't do this at home, kids!
#define md_fu_class int
static const int FUClass_NA = 0;
static const int IntALU = 1;
static const int IntMULT = 2;
...


(Won't probably work out of the box either because of things like "void foo(enum md_fu_class)")


Ciao, Imi.
Topic archived. No new replies allowed.