KhanhPhan
KhanhPhan

Reputation: 1

C++ accessing struct with #define?

I am testing some C++ code. Currently there is one problem that I can not understand the origin of. The code is like this:

        typedef struct
        {
          UWORD tFollowUp_uw;

          union
          {
            UBYTE Control_ub;

            struct
            {
              BITFIELD8 Request_b1  :1;
            }b_st;
          }b_un;
        }X_CONTROLS;

    #define Request_b       (Controls_st.b_un.b_st.Request_b1)
    #define tFollowUp_uw    (Controls_st.tFollowUp_uw)

class Class_T20
{
  public:
      X_CONTROLS Controls_st;
}

So, when I test these LOC, I first declare an object Class_T20_obj.

I can only access the variable Request_b1 by calling Class_T20_obj.Controls_st.b_un.b_st.Request_b1

I can not access the variable tFollowUp_uw by calling Class_T20_obj.Controls_st.tFollowUp_uw

Can anyone help me with this?

Upvotes: 0

Views: 198

Answers (2)

Arne Mertz
Arne Mertz

Reputation: 24576

In your comments you write you want to access the variable. That's easy:

Class_T20_obj.Controls_st.b_un.b_st.Request_b1

Okay, it's a bit work to write that, but its better than that evil macro, in many, many ways. If it's the same Class_T20_obj all the time, you could shorten it by declaring a reference:

BITFIELD8& t20_Request_b = Class_T20_obj.Controls_st.b_un.b_st.Request_b1;
/* do something with t20_Request_b */

Or if you have different objects of type Class_T20 and want to access that member, write a function that returns the reference:

BITFIELD8& get_Request_b(Class_T20& ct20) {
  return ct20.Controls_st.b_un.b_st.Request_b1;
}

//later:
get_Request_b(Class_T20_obj) = someBitFieldValue;

You write you are only testing the code. Use one of the given workarounds, if the author of the code is a foreigner and does not work at your company. I'd put the function inside a header that includes the foreigner's header with the definitions you pasted above like this:

//myxcontrols.h
#include "HIS_XControls.h"

//get rid of the polluting evil macros, they don't work anyways
#undef Request_b
#undef tFollowUp_uw

//free accessor functions
BITFIELD8& get_Request_b(Class_T20& ct20) {
  return ct20.Controls_st.b_un.b_st.Request_b1;
}

But: if the guy who wrote that code is in your company and you have to do acceptance tests, please don't accept it, throw that ugly bit of crapcode back into his face and tell him to make it right and clean. You'll help anybody who has to do with it in the future by not letting them have to cope with the same (and more) problems you have right now. You'll even help himself, although he might not notice at first: He gets the chance to learn and improve and be less cursed on by his fellow programmers.

Upvotes: 0

Mike Seymour
Mike Seymour

Reputation: 254431

I can not access to variable tFollowUp_uw by calling Class_T20_obj.Controls_st.tFollowUp_uw

That's because tFollowUp_uw is an evil macro, so this is converted to

Class_T20_obj.Controls_st.(Controls_st.tFollowUp_uw)

which fails because Controls_st doesn't have a member also called Controls_st; and also because you can't put parentheses around member names like that.

Either use the macro, Class_T20_obj.tFollowUp_uw, after removing the rogue parentheses from it; or get rid of it.

Upvotes: 6

Related Questions