为什么#error指令不能在此处给出预期的结果?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么#error指令不能在此处给出预期的结果?相关的知识,希望对你有一定的参考价值。
我正在为我的AVR ATmega32微控制器编写一个“gpio”设备驱动程序。驱动程序具有初始化功能,如下所示。我使用枚举将配置传递给函数。调用此函数的一个示例是
gpio_init_port(MY_PORT_A, INPUT, HIGH);
这会将PORTA设置为输入,默认值为HIGH。我使用switch语句来检查传递的配置,以将相应的端口设置为输入或输出。现在我想在用户输入错误输入的情况下在switch语句的“default”情况下使用#error preprocessor指令,例如
gpio_init_port(5, INPUT, HIGH);
因此编译停止并打印错误消息。但我不知道为什么它没有像我期望的那样工作。我所指的代码部分是这样的:
default:
#if (port_number != MY_PORT_A && port_number != MY_PORT_B && port_number != MY_PORT_B && port_number!=MY_PORT_D)
#error "Wrong Input. You have entered invalid port number."
#endif
表达方式
(port_number != MY_PORT_A && port_number != MY_PORT_B && port_number != MY_PORT_B && port_number!=MY_PORT_D)
不评估,并且不打印错误消息。但是当我改变它
#if (1)
#error "Wrong Input. You have entered invalid port number."
#endif
它工作正常。我的另一个问题是,当我写一些类似的东西时
gpio_init_port(5, ***OUTPUT***, HIGH);
虽然我这次传递“OUTPUT”,但也会打印错误消息,这不应该发生,因为默认情况仅针对“INPUT”情况定义。
gpio.h
______
typedef enum port_number{
MY_PORT_A=0,
MY_PORT_B,
MY_PORT_C,
MY_PORT_D
} port_number_t;
typedef enum port_direction{
INPUT=0,
OUTPUT
} port_direction_t;
typedef enum output_state{
LOW=0,
HIGH
}output_state_t;
void gpio_init_port(port_number_t port_number, port_direction_t port_direction, output_state_t initial_value);
gpio.c
________
#include "gpio.h"
void gpio_init_port(port_number_t port_number, port_direction_t port_direction, output_state_t initial_value)
{
switch (port_direction)
{
case INPUT:
{
switch (port_number)
{
case MY_PORT_A:
DDRA=0x00;
PORTA=initial_value? 0xff:0x00;
break;
case MY_PORT_B:
DDRB=0x00;
PORTB=initial_value? 0xff:0x00;
break;
case MY_PORT_C:
DDRC=0x00;
PORTC=initial_value? 0xff:0x00;
break;
case MY_PORT_D:
DDRD=0x00;
PORTD=initial_value? 0xff:0x00;
break;
default:
#if (port_number != MY_PORT_A && port_number != MY_PORT_B && port_number != MY_PORT_B && port_number!=MY_PORT_D)
#error "Wrong Input. You have entered invalid port number."
#endif
break;
}
}
case OUTPUT:
{
switch (port_number)
{
case MY_PORT_A:
DDRA=0xff;
PORTA=initial_value? 0xff:0x00;
break;
case MY_PORT_B:
DDRB=0xff;
PORTB=initial_value? 0xff:0x00;
break;
case MY_PORT_C:
DDRC=0xff;
PORTC=initial_value? 0xff:0x00;
break;
case MY_PORT_D:
DDRD=0xff;
PORTD=initial_value? 0xff:0x00;
break;
}
}
}
}
那么,这里究竟是什么错呢?
我已经读过枚举不能用于条件编译,但我不知道这是否真的是正确的以及问题的原因。
提前致谢。
这些陈述
#if (port_number != MY_PORT_A && port_number != MY_PORT_B && port_number != MY_PORT_B && port_number!=MY_PORT_D)
#error "Wrong Input. You have entered invalid port number."
#endif
在预处理/编译时进行评估。因此,无论switch
声明的结果如何,他们都会被评估。在这种情况下,你试图测试port_number
这是#if
宏中的一个变量,这是不可能的。
通常,#error
指令很有用,例如当某些预处理器常量在编译时发生冲突时,肯定不会在运行时发生冲突。你引用的例子
#if (1)
#error "Wrong Input. You have entered invalid port number."
#endif
“有效”(因为它不是很有用),因为1
是一个编译时常量。
您想在运行时测试它,并在运行时抛出一种“异常”:
default:
{
fprintf(stderr,"at %s line %d: Wrong Input. You have entered invalid port number.
",__FILE__,__LINE__);
exit(1);
}
因为所有4个案例都被if
声明排除,所以不需要switch
。
另请注意,您可以插入方便的__FILE__
和__LINE__
编译时值,以便您知道源代码中引发错误的位置(除非您想直接使用assert(0);
)
预处理器#if
只能测试之前已经过#define
的值。它对变量,参数或枚举值一无所知。
而且所有不是来自#define
is given a default macro value of 0。
所以你的测试结果是
#if (0 != 0 && 0 != 0 && 0 != 0 && 0 !=0)
这当然永远不会触发#error
消息。
以上是关于为什么#error指令不能在此处给出预期的结果?的主要内容,如果未能解决你的问题,请参考以下文章
使用 sysdate 时的 Oracle SQL,为啥它没有给出预期的结果