简体   繁体   English

C宏编译器警告

[英]C macro compiler warnings

I've defined a macro, using input from a previous question I asked here . 我已经定义了一个宏,使用的是我在此处提出的上一个问题的输入。 The macro is intended to either set, clear, or check a GPIO pins state. 该宏用于设置,清除或检查GPIO引脚状态。 The macro works as expected however a problem shows up when compiling. 宏可以按预期工作,但是编译时出现问题。 I get compiler warnings anywhere it's used: 在任何使用它的地方都会收到编译器警告:

Warning right-hand operand of comma expression has no effect 警告逗号右手操作数无效

when I use the macro like this: 当我像这样使用宏时:

#define ON  1
#define OFF 2
#define ENA 3
#define OUT_3(x) (x==ON) ? (PORTJ.OUTSET=PIN2_bm) : (x==OFF) ? (PORTJ.OUTCLR=PIN2_bm) : (x==ENA) ? (PORTJ.DIRSET=PIN2_bm) : (PORTJ.DIRCLR=PIN2_bm)
#include <avr/io.h>

if (something) OUT_3(ENA);

However, if I do this: 但是,如果我这样做:

if (something) {OUT_3(ENA);}

I no longer get the warnings. 我不再收到警告。

Why is there a difference? 为什么有区别? How should I alter the macro to prevent this scenario? 我应该如何更改宏以防止出现这种情况?

Additionally this invokes the warning: 此外,这还会引发警告:

int i=0;
if (something) i=1, OUT_3(ENA);

However this does not: 但是,这不是:

int i=0;
if (something) OUT_3(ENA), i=1;

My understanding of comma separated expressions is clearly a bit off. 我对用逗号分隔的表达式的理解显然有些偏离。 How is the compiler seeing this? 编译器如何看待呢? I looked at several other questions similar to this but still do not fully understand the difference. 我查看了与此类似的其他几个问题,但仍然不完全了解其中的区别。

That macro is nasty for several reasons: 该宏令人讨厌,原因如下:

  1. Macro parameters should always be surrounded with parenthesis to avoid potential problems with operator precedence. 宏参数应始终用括号括起来,以避免潜在的运算符优先级问题。 Change (x==ON) to ((x)==ON) . (x==ON)更改为((x)==ON)
  2. Nested ternary operations should be surrounded with parenthesis to make execution order obvious. 嵌套三元运算应使用括号括起来,以使执行顺序显而易见。 Change a ? b : c ? d : e 更改a ? b : c ? d : e a ? b : c ? d : e a ? b : c ? d : e to a ? b : (c ? d : e) a ? b : c ? d : ea ? b : (c ? d : e) a ? b : (c ? d : e) . a ? b : (c ? d : e)
  3. Complete macro should be surrounded with parentheses #define MACRO (...) or do-while-zero loop #define MACRO do {...} while(0) to avoid possible problems with operator precedence. 完整的宏应该用圆括号括起来#define MACRO (...)或do-while-zero循环#define MACRO do {...} while(0)以避免运算符优先级可能出现的问题。 More below. 下面更多。
  4. Ternary operator is not really useful here as you are not using it's return value. 三元运算符在这里并不是真正有用,因为您没有使用它的返回值。 You should rather use regular if or switch statements. 您应该使用常规的if或switch语句。 This is where previously mentioned do-while-zero loop becomes handy: 这是前面提到的“做零时循环”变得很方便的地方:

     #define OUT_3(x) \\ do { \\ if((x) == ON) { PORTJ.OUTSET = PIN2_bm; } \\ else if((x) == OFF) { PORTJ.OUTCLR = PIN2_bm; } \\ else if((x) == ENA) { PORTJ.DIRSET = PIN2_bm; } \\ else { PORTJ.DIRCLR = PIN2_bm; } \\ } while(0) 
  5. But is macro really even necessary? 但是,宏真的必要吗? You could use inline function instead, and get rid of all macro weirdness: 您可以改用内联函数,并消除所有宏怪异:

     static inline void OUT_3(x_type x) { if(x == ON) { PORTJ.OUTSET = PIN2_bm; } else if(x == OFF) { PORTJ.OUTCLR = PIN2_bm; } else if(x == ENA) { PORTJ.DIRSET = PIN2_bm; } else { PORTJ.DIRCLR = PIN2_bm; } } 

With these changes, your error will likely go away, and your code is much easier to read. 通过这些更改,您的错误可能会消失,并且您的代码更容易阅读。

I can't reproduce your issue. 我无法重现您的问题。 This code works without any problem 该代码可以正常工作

main.cpp main.cpp

#include <stdio.h>
enum type{ON, OFF, ENA};

#define OUT_3(x) (x==ON) ? (printf("ON\n")) : (x==OFF) ? (printf("OFF\n")) : (x==ENA) ? (printf("ENA\n")) : (printf("OTHER\n"))

int main(){
  int a = 2;
  if(a == 1) OUT_3(ON);
  if(a == 2) OUT_3(OFF);
  if(a == 3) OUT_3(ENA);

  return 0;
}

Compiled with 编译与

gcc -Wall -O0 -g -o main main.c

Could you please show how the definitions of ON, OFF, ENA and the Port definitions look like? 您能否显示ON,OFF,ENA和端口定义的外观如何?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM