为什么#error指令不能在此处给出预期的结果?

Als*_*isi 1 c embedded microcontroller

我正在为我的AVR ATmega32微控制器编写一个"gpio"设备驱动程序.驱动程序具有初始化功能,如下所示.我使用枚举将配置传递给函数.调用此函数的一个示例是

gpio_init_port(MY_PORT_A, INPUT, HIGH);
Run Code Online (Sandbox Code Playgroud)

这会将PORTA设置为输入,默认值为HIGH.我使用switch语句来检查传递的配置,以将相应的端口设置为输入或输出.现在我想在用户输入错误输入的情况下在switch语句的"default"情况下使用#error preprocessor指令,例如

gpio_init_port(5, INPUT, HIGH);
Run Code Online (Sandbox Code Playgroud)

因此编译停止并打印错误消息.但我不知道为什么它没有按照我的预期运作.我所指的代码部分是这样的:

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
Run Code Online (Sandbox Code Playgroud)

表达方式

(port_number != MY_PORT_A && port_number != MY_PORT_B && port_number != MY_PORT_B && port_number!=MY_PORT_D)
Run Code Online (Sandbox Code Playgroud)

不评估,并且不打印错误消息.但是当我改变它

#if (1)
#error "Wrong Input. You have entered invalid port number."
#endif
Run Code Online (Sandbox Code Playgroud)

它工作正常.我的另一个问题是当我写一些类似的东西时

gpio_init_port(5, ***OUTPUT***, HIGH);
Run Code Online (Sandbox Code Playgroud)

虽然我这次传递"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);
Run Code Online (Sandbox Code Playgroud)
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;  
    }
}
}
}
Run Code Online (Sandbox Code Playgroud)

那么,这里究竟是什么错呢?

我已经读过枚举不能用于条件编译,但我不知道这是否真的是正确的以及问题的原因.

提前致谢.

Jea*_*bre 6

这些陈述

#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
Run Code Online (Sandbox Code Playgroud)

在预处理/编译时进行评估.因此无论结果如何,他们都会被评估switch.在这种情况下,你试图测试port_number哪个是#if宏中的变量,这是不可能的.

通常,该#error指令很有用,例如当某些预处理程序常量在编译时发生冲突,肯定不会在运行时发生冲突.你引用的例子

#if (1)
#error "Wrong Input. You have entered invalid port number."
#endif
Run Code Online (Sandbox Code Playgroud)

"工作"(因为它不是很有用),因为它1是一个编译时常量.

您想在运行时测试它,并在运行时抛出一种"异常":

default:
{
   fprintf(stderr,"at %s line %d: Wrong Input. You have entered invalid port number.\n",__FILE__,__LINE__);
   exit(1);
}
Run Code Online (Sandbox Code Playgroud)

if因为switch声明中已经排除了所有4个案件,所以没有必要.

另请注意,您可以插入方便__FILE____LINE__编译时值,以便知道源代码中引发错误的位置(除非您想assert(0);直接使用)