How do I redefine a data area data area?

I’m not sure what I is called in Arduino c+ but I want to define a single 16bit integer as two 8 bit integers. In cobol it would be a redefines. The data will come in as two bytes but I need to use it as a single 16 bit variable. I’ve seen this uint16_t data= ((msb << 8) | lsb) but would like to do it without the shift operation. If this feature exists what is it called?

If this feature exists what is it called?

There is a macro, word(), that does that behind the scenes. But, why? Adding more code to hide what you don’t want to see doesn’t make sense to me.

Maybe someone wrapped it a nice function but it’s still just a bitshift…

You might do it with a union but as I learned last week, it’s fine on a AVR but it’s not purely defined C++ behavior… So it might not work on other compilers.

So what is against the bitshift?

PS Please use code tags next time. I doubt you out a 8) in there on purpose.

Sorry about missing the code tags. I'll not make that mistake a 2nd time. My goal in the "redefines" is to avoid extra code to build the 16bit variable by loading the two 8bit values into the same area accessed by the 16bit variable name. They are being read in from an external device.

How do you want to magically make a 16-bit out of 2 8-bit’s without code? And uint16_t data= ((msb << 8) | lsb) is just a nice and easy single line.

If you dislike the bit shift, you can multiply.

uint16_t data= msb*256 + lsb;

My goal in the "redefines" is to avoid extra code to build the 16bit variable

Why bother? Even if some "extra" code is required, it's only going to be on the order of a few extra bytes and probably less than a microsecond of execution time.
The compiler might end up optimizing it anyway.

Pete

I honestly haven’t tried this yet, but perhaps something like the following would work:

uint16_t data;
uint8_t *ptr = (uint8_t *)&data;
*ptr = lsb;
*(ptr+1) = msb;

Of course, it’s ugly and depends on whether the processor is Big Endian or Little Endian. But, it does achieve your goal of not using the shift operation.

And breaks on anything that's not 8-bit etc...

Its the endianess that's the issue, we know we are dealing with 8 bit and 16 bit values as
they are declared uint8_t and uint16_t.

In general if you use standard idioms for the bit shifting the compiler will optimize them
according to the machine's endianness - compilers are good at that sort of code-fragment
recognition. And the standard idioms are portable and well-defined.

MarkT:
Its the endianess that's the issue, we know we are dealing with 8 bit and 16 bit values as
they are declared uint8_t and uint16_t.

Yeah, but I doubt a 32-bit will not just use a 32-bit register for a 8-bit. So the pointer to the next 8-bit will point to the next register so not magically to the middle of the same register where the next 8-bit is...

But I'm nut sure and the compiler might do some smart stuff to save memory when dealing with variables smaller then it's native size but I doubt it.

Point being, use the shift operator.

jrdarrah:
My goal in the "redefines" is to avoid extra code to build the 16bit variable by loading the two 8bit values into the same area accessed by the 16bit variable name.

Cobol has to add the "extra code" behind the scenes. Just because some other language lets you do complex things in a compact way (I am looking at you, APL!) does not mean that it takes any less code space or time.

I widened my search and found that using union would do exactly what I wanted. For my app, space isn’t as important as speed. In the scheme of things this method might not be much faster than the boolean ops to build the 16bit data from two 8 bit variables read in from the mpr121. The output of this sketch is , assuming 0000 on the beginning of the touchData binary data.

Status 01 - 1100
Status 00 - 1010
TouchData 110000001010

This allows me to use touchData directly as a side effect of reading the data into status00 and staus01.

typedef union mpr121Data 
{
  uint16_t touchData;
  struct
  {
    byte status01;
    byte status00;
  } statusData;
}mpr121Data;

void setup() {
  mpr121Data sensorInput;
  // put your setup code here, to run once:
  unsigned long delayStart = millis();
  Serial.begin(57600);
  while (!Serial && (millis() - delayStart) <= 4000);
  delay(500);
  sensorInput.statusData.status00 = 12;
  sensorInput.statusData.status01 = 10;
  Serial.print("Status 01 - ");
  Serial.println(sensorInput.statusData.status00,BIN);
  Serial.print("Status 00 - ");
  Serial.println(sensorInput.statusData.status01,BIN);
  Serial.print("TouchData ");
  Serial.println(sensorInput.touchData,BIN);
}

void loop() {
  // put your main code here, to run repeatedly:

}

jrdarrah:
I widened my search and found that using union would do exactly what I wanted.

Bit you didn’t widened it enough… Because like I told you (reply 2), it works fine on a AVR but is undefined in C++ in general…

And have you checked what the compiler makes of it? For all you know it does it by shifting… It’s higher level, you have no idea what the compiler makes of it.

And I wouldn’t even be suprised if the compiler was smart enough to optimize

uint16_t data= ((msb << 8) | lsb)

into really putting msb into the msb register (without shifting) and lsb in lsb. But I didn’t bother to check.

But what on earth are you making that is THAT time critical?

jrdarrah:
In the scheme of things this method might not be much faster than the boolean ops to build the 16bit data from two 8 bit variables read in from the mpr121.

It won't be.

Quote from K&R ‘The C Programming Language”, second edition:

“It is the programmer’s responsibility to keep track of which type is currently stored in a union; the results are implementation-dependent if something is stored as one type and extracted as another”

jrdarrah:
I'm not sure what I is called in Arduino c+ but I want to define a single 16bit integer as two 8 bit integers. In cobol it would be a redefines.

In C, it's a union.

union Foo {
  int a;
  struct Split {
    byte part1;
    byte part2;
  } b;
} foo;