2

As far as I know, if I have a class such as the following:

class TileSurface{
   public:
      Tile * tile;
      enum Type{
         Top,
         Left,
         Right
      };
      Type type;
      Point2D screenverts[4]; // it's a rectangle.. so..
      TileSurface(Tile * thetile, Type thetype);
};

There's no easy way to programatically (using templates or whatever) go through each member and do things like print their types (for example, typeinfo's typeid(Tile).name()).

Being able to loop through them would be a useful and easy way to generate class size reports, etc. Is this impossible to do, or is there a way (even using external tools) for this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kamziro
  • 7,882
  • 9
  • 55
  • 78

6 Answers6

2

Simply not possible in C++. You would need something like Reflection to implement this, which C++ doesn't have.

As far as your code is concerned after it is compiled, the "class" doesn't exist -- the names of the variables as well as their types have no meaning in assembly, and therefore they aren't encoded into the binary.

(Note: When I say "Not possible in C++" I mean "not possible to do built into the language" -- you could of course write a C++ parser in C++ which could implement this sort of thing...)

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • "You could write a C++ parser ..." Not if he wants to actually have a life. This takes man-years of effort. – Ira Baxter Dec 30 '10 at 11:05
1

I beg to differ from the conventional wisdom. C++ does have it; it's not part of the C++ standard, but every single C++ compiler I've seen emits metadata of this sort for use by the debugger.

Moreover, two formats for the debug database cover almost all modern compilers: pdb (the Microsoft format) and dwarf2 (just about everything else).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1

No. There are no easy way. If to put "easy way" aside then with C++ you can do anything imaginable.

If you want just to dump your data contents run-time then simplest way is to implement operator<<(ostream&,YourClass const&) for each YourClass you are interested in. Bit more complex is to implement visitor pattern, but with visitor pattern you may have different reports done by different visitors and also the visitors may do other things, not only generate reports.

If you want it as static analysis (program is not running, you want to generate reports) then you can use debugger database. Alternatively you may analyze AST generated by some compilers (g++ and CLang have options to generate it) and generate reports from it.

If you really need run-time reflection then you have to build it into your classes. That involves overhead. For example you may use common base-classes and put all data members of classes into array too. It is often done to communicate with applications written in languages that have reflection on more equal grounds (oldest example is Lisp).

Öö Tiib
  • 10,809
  • 25
  • 44
  • g++ generated AST? I didn't think of that, great idea! – kamziro Dec 30 '10 at 20:10
  • @kamziro: If you want anything beyond raw syntax (e.g., the "type information" for a class member), you will need more than just the AST. GCC has a lot of internal data (after all, it *is* a compiler) and if you work hard enough you can likely extract a lot. – Ira Baxter Dec 30 '10 at 23:59
0

If you derive all types of the member variables from your common typeinfo-provider-baseclass, then you can get that. It is a bit more work than like in Java, but possible.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ch0kee
  • 736
  • 4
  • 12
0

External tools: you mentioned that you need reports like class size, etc.--

Doxygen could help http://www.doxygen.nl/manual/features.html to generate class member lists (including inherited members).

albert
  • 8,285
  • 3
  • 19
  • 32
kbsant
  • 136
  • 3
0

Our DMS Software Reengineering Toolkit is what you call an "external tool" for extractingt/transforming arbitrary code. DMS is generalized compiler technology parameterized by explicit langauge definitions. It has language definitions for C, C++, Java, COBOL, PHP, ...

For C, C++, Java and COBOL versions, it provides complete access to parse trees, and symbol table information. That symbol table information includes the kind of data you are likely to want from "reflection". If you goal is to enumerate some set of fields or methods and do something with them, DMS can be used to transform the code (or generate derived code) according to what you find in the symbol tables in arbitrary ways.

Ira Baxter
  • 93,541
  • 22
  • 172
  • 341