c/c++ 预处理器是否处理所有以 # 开头的行?遇到未知宏时会出错还是会忽略它们?
举个例子,
#include <stdio.h>
#hello
int main(){
printf("Hello World!");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下会发生什么?它会产生错误还是会起作用(忽略#hello行)?
以下代码不扩展布尔表达式,另请参见https://godbolt.org/z/YqbazT3eo:
#define EXPAND(x) x
#define SWITCH false
EXPAND(SWITCH || defined(_DEBUG))
Run Code Online (Sandbox Code Playgroud)
我该如何正确地做才能做到
#define FLAG EXPAND(SWITCH || defined(_DEBUG))
Run Code Online (Sandbox Code Playgroud)
(或类似)并且FLAG不会依赖于以后的更改SWITCH?
C 宏是否可以具有任何状态?在本例中,为整数值。
我希望能够从静态分配的缓冲区中分配一些内存,因为我处于嵌入式环境中。假设我有一个像这样的结构和一个缓冲区:
double buffer[1000];
typedef struct {
int rows;
int cols;
double* data;
} matrix;
Run Code Online (Sandbox Code Playgroud)
我想要一个可以生成矩阵并从相关缓冲区分配相关内存的宏。然而,我似乎想不出一种方法来保存内部计数器来确定我们目前应该在缓冲区中的位置。理想情况下,宏应该是这样的:
#define alloc_matrix(_rows, _cols) {.rows = _rows, .cols = _cols, .data = &buffer[PTR]}
Run Code Online (Sandbox Code Playgroud)
其中 PTR 是编译时间常数,每次使用 alloc_matrix 时都会不断变化(按行 * 列增加)。这将允许我在编译时使用 _Static_assert 之类的东西检查所有内容是否适合缓冲区,而不是在运行时检查所有内容。
这可以用 C 预处理器实现吗?
我尝试过使用 C 预处理器,但似乎找不到在宏中存储状态的方法。
我想在我的程序中进行条件编译.我知道如果你声明一个public static final boolean,编译器将忽略未遍历的分支.在构建程序之前,是否可以让ant目标更改变量?
例如,如果我有:
final public static boolean windows = false;
我想要两个蚂蚁目标:Windows和Mac.我希望命令
ant windows
将布尔值更改为true,同时
ant mac
保留变量.
谢谢.
我正在使用gfortran编译FORTRAN 77,并希望通过使用预处理器指令#ifdef来获得DEBUG构建选项.但是,当我使用它们时,我得到编译时警告"非法预处理程序指令".是否可以在不偏离标准工具链的情况下使用此功能?
我在整个代码中都使用了此代码:
#pragma message "FIXME: this needs to be fixed"
Run Code Online (Sandbox Code Playgroud)
我希望这些警告消息仅对启用它们的用户显示。我以为我会为此写一个宏,例如:
#ifdef SHOW_DEVELOPER_MESSAGES
#define DEVELOPER_MESSAGE(msg) _Pragma("message " ## msg)
#endif
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
DEVELOPER_MESSAGE("TEST: -- xxxx --")
Run Code Online (Sandbox Code Playgroud)
但这导致以下错误:
Pasting formed '"message ""TEST: -- xxxxx --"', an invalid preprocessing token
Run Code Online (Sandbox Code Playgroud)
我已经阅读了C / C ++宏字符串连接并尝试使用它,但是我无法使其正常工作。我在想这样做必须使消息必须像这样用转义的引号引起来(这种工作方式我只是不知道如何创建像这样的转义的字符串来与_Pragma一起使用):
_Pragma("message \"THIS is the actual message!\"")
Run Code Online (Sandbox Code Playgroud)
如何创建打印出编译指示消息的宏(或类似的解决方案)?
解决方案应该是单线的,将每一个实用信息#ifdef SHOW_DEVELOPER_MESSAGES都包含在内,这将违背此练习的目的。
奖励问题:如何更改宏以为不同的消息类型创建不同的变体,例如:
DEVELOPER_FIXME("bug")
Run Code Online (Sandbox Code Playgroud)
它总是与FIXME前缀字符串到形式:"FIXME: bug"。
以下声明是一种简写吗?我需要有人帮助我理解它.
#define clean_errno()(errno == 0? "None": strerror(errno))
Run Code Online (Sandbox Code Playgroud)
从执行结果,我想这意味着一旦我面对clean_errno(),如果errno ==0我更换clearn_errno()用None,如果没有,我代替clean__errno()用strerror(errno).但我不知道如何从逻辑上分析这个陈述?
微控制器有许多引脚,每个引脚都定义为
const Leg PA29 { PIOA, BIT(29) }; // struct Pin is already taken
// ... about 120 more: 4 port x 32 pin
Run Code Online (Sandbox Code Playgroud)
我define用简短的形式写了一个简单的别名
#define P(Port,PinN) \
const Leg P##Port##PinN { PIO##Port, BIT(PinN) }
Run Code Online (Sandbox Code Playgroud)
用它作为
P(D,2); //produces PD2 with { PIOD, BIT(2) }
Run Code Online (Sandbox Code Playgroud)
尼斯.
现在我需要 - 不会P在4个端口上调用120次以上,每个端口有32个引脚.我想看到类似的东西
FOR_EACH( X in A,B,C,D ) \
FOR_EACH( i in 0..31 ) \
P(X,i);
Run Code Online (Sandbox Code Playgroud)
请不要建议TCL,python等生成C++代码.
我找到了答案,但要理解如何在我的案例中使用它是很复杂的.
主要思想是避免120行复制粘贴.所有120多个引脚应定义为大约10行.
UPD.如何BIT定义:
///@param n is value from 0 to …Run Code Online (Sandbox Code Playgroud) 我正在用C++构建自己的终端应用程序项目,我问自己标准库是否有ifdef或ifndef预处理器指令.我想知道,因为我需要创建不同的头文件,需要一些标准库头文件,如"字符串"和其他一些,我不想包括相同的库3次或更多次,因为它使程序更重.
例如,我在我的头文件上写了这样的东西,以防止.h文件被包含多次:
#ifndef myheader_h
#define myheader_h
// my file code here
#endif
Run Code Online (Sandbox Code Playgroud)
我尝试编译,但编译器没有说错误或警告.
我还尝试阅读标准库源代码(https://en.cppreference.com/w/cpp/header),但我没有找到任何预处理器规则,如ifdef或ifndef.
我应该包括这样的标准库标题吗?
#ifndef string_h
#define string_h
#include <string>
#endif
Run Code Online (Sandbox Code Playgroud)
我希望我的问题还没有被问到,因为我在搜索时没有找到它.
对于那些说"你不在你需要担心的位置"的人,以及谁说"如果它有适当的包括警卫就花费很少",我的意思是:程序的沉重很重要,我想让它变得更轻松所以我不想多次完全包含同一个文件.有std lib文件正确包含警卫吗?(我的头文件有它们,不知道std lib文件)