Compiler warnings making me nuts

Status
Not open for further replies.

Detroit_Aristo

Well-known member
I am trying to use a define macro to handle the millions of conversions I have to do a second and I am getting tons of warnings. Will someone with more compiled switching and __attribute__ knowledge take a stab at educating me?
Code:
#define BYTE_TO_BINARY(byte) ((byte & 0x80 ? '1' : '0'), \
	(byte & 0x40 ? '1' : '0'), \
	(byte & 0x20 ? '1' : '0'), \
	(byte & 0x10 ? '1' : '0'), \
	(byte & 0x08 ? '1' : '0'), \
	(byte & 0x04 ? '1' : '0'), \
	(byte & 0x02 ? '1' : '0'), \
	(byte & 0x01 ? '1' : '0') )
Warning:
Code:
decode.cpp:156: note  in expansion of macro BYTE_TO_BINARY
   CompleteSwappedBytes = BYTE_TO_BINARY(CompleteSwappedBytes >> 8), BYTE_TO_BINARY(CompleteSwappedBytes)
warning: second operand of conditional expression has no effect [-Wunused-value]

I am just not sure how to make the compiler happy in this instance.

Thanks Ladies and Gents!
 
That looks like a set of 8 conditional expressions giving '1' or '0' strung together - 8 intermediate results going nowhere and used for nothing - the compiler is making note there is no assignment or use of the result that is as the compiler notes: expression has no effect.

Where should these bits to go after they are broken out? How are they to be used?
 
Last edited:
It's supposed to give me the bits from a value. I am taking up to 4 bytes and I need the binary representation.

The bits are being put into an array of 2 or 4 bytes.

I thought the macro would be elegant and simple, but it's anything but. I should write a function that does the same and returns the int value.

Data comes in as big endian. It's an 8 byte array, but some values are cross byte boundaries. That is There might be 4 flags in byte 0 (bits 0 to 3), but then I need the next 16 bits (bits 4 to 19) in order for a uint16_t value.

Sorry if my explanation is a bit vague.
 
I don't understand.
'1' or '0' is a char

A char is 8 bits. a bit is a 1 or a 0. There are 8 possible values in a single char data type. For example. declaring a bool will allocate 8 bits (1 byte) and use 1 of those bits. Declaring a unsigned char and performing bitwise operations will compact the code by 8 times, as I can now put 8 boolean flags in a single unsigned char.
 
Yeah, but it's still not clear what you want..
if you want to save memory (does not really makes sense on a Teensy), you can use something like this:
Code:
struct flags {
uint8_t threebits:3, a:1, b:1, c:1, d:1, e:1;
};
But this again has nothing to do with a macro..

Edit: Maybe you want a "union" with a byte and 8 bits?
 
Last edited:
Your explanation makes no sense.

Your are building a comma expression that results in something like:
('0', '0', '1')

Everything but the '1' gets thrown away. That's what the compiler is telling you.
 
Are these bits for repeated access or just occasional testing? Perhaps this will lead to a solution ...

I was going to write this - but searched instead ::
Code:
[URL="http://stackoverflow.com/questions/523724/c-c-check-if-one-bit-is-set-in-i-e-int-variable"]#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))[/URL]
 
I should write a function that does the same and returns the int value.

Yes, you probably should write it as a function. You can give it the always_inline attribute to get the same sort of inline optimization you're expecting from a preprocessor macro. But unlike a macro, you'll be able to specify the input and output types and write the code more clearly. The compiler will give you much better errors and warnings too.
 
Yes, you probably should write it as a function. You can give it the always_inline attribute to get the same sort of inline optimization you're expecting from a preprocessor macro. But unlike a macro, you'll be able to specify the input and output types and write the code more clearly. The compiler will give you much better errors and warnings too.

Thank you Paul. That will work out for me.

The idea is that I have a stream from a CAN bus at 1,000,000 bits/sec and I am trying to write a decode. Some of the messages contain multi-byte values and I need to flip the data very quickly (or risk overflowing the buffers), so that I can be decoded, converted, then sent out via RS232 to an LCD dashboard. For Example, on ID 0x144 bits 31 to 16 the message is "Injector Pulse Width" and it's in microseconds. The data will be say, 00000001 00000100 . The actual value is 401(H) and 1025(D).

Now I am confusing myself. hahaha. I need to do some more design work. I have 34 IDs to decode and something like 200 variables of differing bit length. Some overlap bytes, but it's not symmetric. That is, on one ID, Say, 0x145 the first 4 bits in the stream are single-bit flags, then the next 16 are a single variable value. That puts the 16-bit variable on bytes 0, 1, and 2.

I'll get it working. I was trying to use macros, but inlining the function is a much better option.

I genuinely appreciate all the information here and your input.
 
My Bitwise operations and boolean math need tons of rust knocked off. Sheesh.

I just can't seem to get this. Brain block.

Code:
inline uint16_t getDoubleValueFromTwoBytes(uint8_t byte1In, uint8_t byte2In)
{
	return ((uint16_t)byte2In << 8) | byte1In;

};

I am so dumb sometimes.

byte2In was 0x40, and byte1In was 0x1. It was working, I just couldn't see that I was an idiot. It should have been byte2In 0x4 and byte1In 0x01
 
Last edited:
I need to flip the data very quickly

Always get something working the simplest way first. Then measure it's actual speed. These chips do bit shift and logic very fast, so odds are good it'll be plenty fast enough for something modest speed like only 1 Mbit/sec CAN. Sure, that may seem fast because it's the top speed for CAN... but consider the Teensy Audio lib processes stereo audio (which is 1.4 Mbit/sec) with a tremendous amount of capability to do advanced effects & filters. Just shuffling some bits around at these speeds is actually pretty lightweight work for Teensy 3.x.

If you do need to run faster, or if you just like the challenge of optimization, we can try to help here. The best way to ask starts by posting that simplest-possible code. Here's an old thread where you can see the pretty dramatic results we tend to accomplish here....

https://forum.pjrc.com/threads/28932-LC-is-10-9-times-slower-than-T3-1

But the path to success always starts with a slow but simple and fully functional program, and always posting complete programs that anyone here can copy into Arduino and actually run. Many of us do tend to get pretty obsessive-compulsive about speed optimizing code. But that only occurs when it's complete code anyone can run on their board and benchmark the results of optimization ideas.
 
Last edited:
Understandable Paul. I appreciate your input, as always.

It's working now and I intend on loading both CAN lines with 1Mbit/sec as a test. It's going into a vehicle and is being used to bridge CAN to RS232.
 
Status
Not open for further replies.
Back
Top