Tag: c preprocessor

有没有办法检查宏是否已定义,并且它同时等于某个值

我经常使用类似对象的预处理器宏作为C代码中的布尔标志来打开和关闭代码段。 例如 #define DEBUG_PRINT 1 然后像使用它一样 #if(DEBUG_PRINT == 1) printf(“%s”, “Testing”); #endif 但是,如果包含#define的头文件忘记包含在源代码中,则会出现问题。 由于未声明宏,因此预处理器将其视为等于0,并且#if语句永远不会运行。 当忘记包含头文件时,可能发生非预期的,不守规矩的行为。 理想情况下,我希望能够检查宏是否已定义,并在一行中检查它是否等于某个值。 如果未定义,则预处理器会抛出错误(或警告)。 我正在寻找以下内容: #if-def-and-true-else-throw-error(DEBUG_PRINT) … #endif 它就像#ifdef和#if的组合,如果它不存在,则使用#error 。 我已经探索了一些途径,但是,预处理器指令不能在#define块中使用,据我所知,如果在内部使用宏时没有定义宏,则没有预处理器选项来抛出错误/警告#if语句。

C / C ++预处理器宏可以有默认参数值吗?

我们可以为宏参数指定默认参数值吗? 我知道没有任何类型检查,所以我希望默认值只不过是预处理器在未指定参数值的情况下用于宏扩展的一些文本。

为什么这个嵌套的宏替换失败了?

我正在尝试应用X宏概念,以便有可能将所有struct成员初始化为自定义默认(无效)值。 我写下面的代码: #define LIST_OF_STRUCT_MEMBERS_foo \ X(a) \ X(b) \ X(c) #define X(name) int name; struct foo { LIST_OF_STRUCT_MEMBERS_foo }; #undef X #define X(name) -1, static inline void foo_invalidate(struct foo* in) { *in = (struct foo){ LIST_OF_STRUCT_MEMBERS_foo }; } #undef X #define X(name) -1, #define foo_DEFAULT_VALUE { LIST_OF_STRUCT_MEMBERS_foo } #undef X static struct foo test = […]

gcc和Microsoft预处理器之间的区别

我发现Microsoft Visual Studio编译器和gcc以不同的方式预处理以下小片段: # define M3(x, y, z) x + y + z # define M2(x, y) M3(x, y) # define P(x, y) {x, y} # define M(x, y) M2(x, P(x, y)) M(a, b) ‘gcc -E’给出以下内容: a + {a + b} ,’cl / E’发出关于缺少宏参数的警告并产生以下输出: a + {a, b} + 似乎来自嵌套宏扩展的逗号不被视为参数分隔符。 不幸的是,我没有找到cl预处理器中实现的算法的描述,所以我不确定我的建议是否正确。 有谁知道cl预处理器是如何工作的,它的算法和gcc之间有什么区别? 以及如何解释观察到的行为?

为什么人们使用#ifdef进行function标记测试?

人们建议#ifdef进行大范围的条件编译 。 搜索#ifdef证实它的使用是普遍的。 然而#ifdef NAME (或等效的#if defined(NAME)和相关的#ifndef NAME (和#if !defined(NAME) )有一个严重的缺陷: header.h #ifndef IS_SPECIAL #error You’re not special enough #endif source.cpp #include “header.h” gcc -DIS_SPECIAL source.cpp 显然,将会通过 source1.cpp #define IS_SPECIAL 1 #include “header.h” 但是,也一样 source0.cpp #define IS_SPECIAL 0 #include “header.h” 这是完全错误的事情。 一些C ++编译器,传递一个以C模式处理的文件(由于扩展或命令行选项)有效地执行#define __cplusplus 0 。 我看到事情破裂了 #ifdef __cplusplus extern “C” { #endif /* … […]

使用宏进行类型generics编程:确定类型的技巧?

可以将某些类型的类型generics函数作为C中的宏来执行,例如: #define SQRT(x) (sizeof(x) == sizeof(float) ? sqrtf((x)) : \ sizeof(x) == sizeof(double) ? sqrt((x)) : \ sqrtl((x)) ) 只要x是浮点类型,这(大多数情况下)就可以正常工作。 但是,如果我想要一个可以采用整数类型或指针类型的类型通用宏,它可能具有相同的大小。 有没有一种聪明的方法来测试宏参数是整数还是指针? 整数与浮点类型怎么样?

在C中定义数组

我有几个450元素字符数组(存储在lcd屏幕上显示的位图数据。)我想将它们放在头文件下并#define它们,但我不断收到编译错误。 我怎么用C做这个? #define numbers[450] {0, 1,etc…} #define numbers {0, 1, etc…} #define numbers[450]然后设置数字 还有很多…

宏评估订单

可能重复: 宏中的#和## 为什么第二个printf的输出是f(1,2)什么是宏的评估顺序? #include #define f(a,b) a##b #define g(a) #a #define h(a) g(a) int main() { printf(“%s\n”,h(f(1,2))); printf(“%s\n”,g(f(1,2))); return 0; } output 12 f(1,2)

#define vs. enums用于寻址外设

我必须在基于ARM9的微控制器中编程外设寄存器。 例如,对于USART,我将相关的内存地址存储在enum : enum USART { US_BASE = (int) 0xFFFC4000, US_BRGR = US_BASE + 0x16, //… }; 然后,我在函数中使用指针来初始化寄存器: void init_usart (void) { vuint* pBRGR = (vuint*) US_BRGR; *pBRGR = 0x030C; //… } 但我的老师说我最好使用#define ,例如: #define US_BASE (0xFFFC4000) #define US_BRGR (US_BASE + 0x16) #define pBRGR ((vuint*) US_BRGR) void init_usart (void) { *pBRGR = 0x030C; } 他说,就像这样,你没有在堆栈中分配指针的开销。 […]

-Werror导致编译器在#warning上停止。 我该怎么做才能防止这种情况发生?

首先,我希望它停止警告。 但我也希望打印出一些信息性的消息(比如“回来实现这个!”)。 不幸的是,我的编译器不支持#info #message , #pragma message() , #pragma message()等。 我知道有-Wno-error= ,但我的google-foo很弱,我似乎无法找到#warning的 。 我试过-Wno-error=warning ,只是说“没有 – -Wwarning ”。 与“ warn ”相同。 有什么建议? 值得一提的是,我使用的是Tensilica xtensa编译器,xt-xcc,它似乎是一个gnu派生词,或者至少使用了gnu前端。 它的版本是8.0.0。