• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 247
  • Last Modified:

implementation details


Consider
 struct MSG_HEADER
{
     unsinged int  count       :   9;
     unsigned int  msg_id     : 7;
}

Then later a C function that parse out msg_id from the contents of 'buffer' below

void SomeProcessing()
{
  char  buffer[512];
  MSG_HEADER id, aa;

  // get data from buffer
  // later strip out the id
  id = ((MSG_HEADER *)buffer)->msg_id;
  aa = (((( id >> 4 ) & 0x07) <<3 )) | ( id & ox07 );

  // then later
  // switch (type)
     {
       case A
         // stuff
         break;
       case B
         // stuff
         break;
       case C
         // stuff
         break;
         // more case statements
       default:
         break;
      }
}

Re-writign in C++
void MY_CLASS::SomeProcessing()
{
  char  buffer[512];
  // later

   // inside of SomeProcessing I'll call SomeSpecialProcessing
   SomeSpecialProcessing (&buffer[0]);
}

void MY_CLASS::SomeSpecialProcessing( unsigned char * ptr)
{
    what would be the C++ version look like for 'id' and type?  Want to ensure my version is  right in my code.
    // id = ((MSG_HEADER *)buffer)->msg_id;
//  aa = (((( id >> 4 ) & 0x07) <<3 )) | ( id & 0x07 );  // could perhaps make this more easily understood?

I'm under the impression that case statements could be viewed as poor design from a C++ context.  That said, how would i get around the 'case' statements in the C code?
}
0
forums_mp
Asked:
forums_mp
1 Solution
 
efnCommented:
>   SomeSpecialProcessing (&buffer[0]);

You could just use "buffer" instead of "&buffer[0]"; it means the same thing.

> what would be the C++ version look like for 'id' and type?

There is no need for it to be different.  C++ is not significantly different from C when it comes to low-level bit-twiddling.

> //  aa = (((( id >> 4 ) & 0x07) <<3 )) | ( id & 0x07 );  // could perhaps make this more easily understood?

I suppose.  Here's a possibility.

// Get bits 4-6
aa = (id & 0x70);

// Shift right one bit.
aa >>= 1;

// Add bits 0-2 of id.
aa |= (id & 0x07);

It's a matter of opinion whether this is more readable.

> I'm under the impression that case statements could be viewed as poor design from a C++ context.  That said, how would i get around the 'case' statements in the C code?

You may not be able to, and you probably shouldn't try without understanding where the bad design rap comes from.

The only switch statement design guideline I know is that you might be able to have simpler, cleaner code by using virtual functions.

For example, instead of:

switch (animal.type)
{
case CANARY:
  animal.sing();
  break;

case DOG:
  animal.bark();
  break;

case CAT:
  animal.meow();
  break;
}

you could have a base class animal with a virtual function speak().  Then you could have derived classes canary, dog, and cat that implement the speak function appropriately for their species, so instead of the switch statement, you can just code:

animal.speak();

and get appropriate behavior.

This transformation is not necessarily helpful in every situation where one might use a switch statement.  From the information you have provided, it's not clear whether a design with inheritance and virtual functions would be an improvement in your application.

--efn
0
 
DanRollinsCommented:
>> I'm under the impression that case statements could be viewed as poor design from a C++ context.

You are under a false impression.  The switch/case construct is an excellent way to process n-way decisions in any language.

-- Dan
0
 
forums_mpAuthor Commented:

In a previous post I had a template class that'll i'll use to store and retrieve current and previous data.

A synopsis

template <class T>
class BUFFER
{
public:
 
  BUFFER();      
  ~BUFFER();  
  void Retieve ( T& data);
   // more stuff
private:
  static const int SIZE = 2;
  T msg [ SIZE ];    
};

// lets suppose I had
struct MSG
{
  unsigned char   aa : 8;
}

// declared once
BUFFER<MSG> msg;
MSG local;

The template implementation has memcopy and into 'local' the contents received from a buffer and handled in a separate 'Store' function.

So now..  I have two asynchronous processes inside FOO.  Lets suppose DoSomething is being run at 900Hz and DoSomeOtherThing is being interrupt driven.  The question is there a potential problem with both accessing the same object and 'local' variable?

void FOO::DoSomething()
{
   msg.Retrieve ( local );
}

void FOO::DoSomeOtherThing()
{
   msg.Retrieve( local );
}
0
 
efnCommented:
> The question is there a potential problem with both accessing the same object and 'local' variable?

Probably.  But your question is not quite well-defined enough to give a definitive answer.

FOO is not defined in this question and it's not clear what you mean by "asynchronous processes inside FOO."  Usually, an operating system can run multiple processes, and each process can have multiple threads.  In your case, you might have multiple processes or threads sharing an object of class FOO.  The techniques for sharing an object across processes are different from the techniques for sharing an object across threads.  Either way, the functions to use are platform-dependent.

But it's likely that some kind of synchronization will be required.

--efn
0
 
migoEXCommented:
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept efn's comment as answer.

Please leave any comments here within the next four days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

migoEX
EE Cleanup Volunteer
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now