1

I need to modify the ordering of my C++ class members. For example:

class B {
public:
int i;
int j;
int k;
...
};

becomes

class B {
public:
int j;
int k;
int i;
...
};

The problem is there are weird codes in my large code bases that depend on relative location of the class members. For example some functions would assume address of member j is smaller than that of member k.

Is there any CASE tool that can help me to identify any code that read the address of a class member?

JavaMan
  • 4,954
  • 4
  • 41
  • 69
  • 1
    Seems like an XY question. What are you ACTUALLY trying to achieve? – Mats Petersson Jun 08 '13 at 10:07
  • Some clever guys (who have left) wrote some codes that assume the relative ordering of the class members. I need to figure out where those codes are and fix them using the smallest amount of time – JavaMan Jun 08 '13 at 10:09
  • How many classes do you have, and will re-ordering the objects show the problem immediately? – Mats Petersson Jun 08 '13 at 10:12
  • Hundreds of classes. There is no compile time error and we need to run a lot of tests to see the error. – JavaMan Jun 08 '13 at 10:14
  • Why do you need to change the ordering? – juanchopanza Jun 08 '13 at 10:21
  • 1
    Sorry for the bad wording. I just need to make sure someone who maintain the code in the future can assume the ordering is irrelevant. I don't really need to change the ordering. – JavaMan Jun 08 '13 at 10:23

1 Answers1

3

I am not aware of any tool that solve your problem, but I would define a class which supports all operators for int type and which overloads ampersand operator so that the result of the operator cannot be casted to a pointer. Then I'd use this class instead of int in your class member definitions and look at places where compiler gives errors.

Something like

class IntWrapper {
 public:
  IntWrapper() { }
  IntWrapper(const int x) { }         // don't care about implementation as we 
  operator int() const { return 0; }  // want compile-time errors only
  IntWrapper& operator ++() { return *this; }
  IntWrapper& operator ++(int) { return *this; }

  ...
  void operator &() const { } // make it void so it would cause compiler error
};

And then:

class B {
 public:
  IntWrapper i;
  IntWrapper j;
  IntWrapper k;
 ...
};

This will not help against using boost::addressof function or some dirty reinterpret_cast of a reference, but addressof is probably never used at all in your project, as well as the reinterpret_cast<char&> trick (who would use it for plain integers?).

You should also care about taking an address of the whole object of B class.

nullptr
  • 11,008
  • 1
  • 23
  • 18
  • my source codes use a lot of c++ standard offsetof() macro which is just implemented as reinterpret_cast in VC++. Are there any other possible ways to get the offset of a member? – JavaMan Jun 08 '13 at 12:12
  • It's possible to redefine `offsetof(s,m)` as `(size_t)&( ((s*)0) -> m)`, so it uses operator `&` for the source type. But it could be easier just to search for `offsetof(class B,` through the whole project. – nullptr Jun 08 '13 at 12:26
  • Sorry, I meant searching for `offsetof(B,`. – nullptr Jun 08 '13 at 12:37
  • To find `offsetof` issues, change to `Intwrapper` and compile with GCC. It warns you about attempts to use `offsetof` on UDTs. – MSalters Jun 09 '13 at 00:48