Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 15 of 15

Thread: Compiler warnings making me nuts

  1. #1
    Senior Member
    Join Date
    Dec 2016
    Location
    Detroit, Michigan, USA
    Posts
    104

    Compiler warnings making me nuts

    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!

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,176
    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 by defragster; 03-08-2017 at 06:17 AM.

  3. #3
    Senior Member
    Join Date
    Dec 2016
    Location
    Detroit, Michigan, USA
    Posts
    104
    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.

  4. #4
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    6,920
    I don't understand.
    '1' or '0' is a char

  5. #5
    Senior Member
    Join Date
    Dec 2016
    Location
    Detroit, Michigan, USA
    Posts
    104
    Quote Originally Posted by Frank B View Post
    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.

  6. #6
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    6,920
    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 by Frank B; 03-07-2017 at 08:52 PM.

  7. #7
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    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.

  8. #8
    Senior Member
    Join Date
    Dec 2016
    Location
    Detroit, Michigan, USA
    Posts
    104
    I'll rewrite it.

    appreciate all the input for sure!

  9. #9
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,416
    Quote Originally Posted by Frank B View Post
    if you want to save memory (does not really makes sense on a Teensy)
    Don't encourage people to write badly bloated code :P

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,176
    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 ::

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,458
    Quote Originally Posted by Detroit_Aristo View Post
    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.

  12. #12
    Senior Member
    Join Date
    Dec 2016
    Location
    Detroit, Michigan, USA
    Posts
    104
    Quote Originally Posted by PaulStoffregen View Post
    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.

  13. #13
    Senior Member
    Join Date
    Dec 2016
    Location
    Detroit, Michigan, USA
    Posts
    104
    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 by Detroit_Aristo; 03-09-2017 at 03:35 AM.

  14. #14
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,458
    Quote Originally Posted by Detroit_Aristo View Post
    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...ower-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 by PaulStoffregen; 03-09-2017 at 12:41 PM.

  15. #15
    Senior Member
    Join Date
    Dec 2016
    Location
    Detroit, Michigan, USA
    Posts
    104
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •