Tag: c preprocessor

从C ++宏创建字符串列表和枚举列表

为了使我的代码更短更容易更改,我想替换类似的东西 enum{ E_AAA, E_BBB, E_CCC }; static const char *strings{“AAA”, “BBB”, “CCC” }; 使用宏,如INIT(AAA,BBB,CCC); 但是当我尝试使用变量参数和字符串化做一个宏时,我得到一个错误,因为没有声明参数。 有关如何做到这一点的任何想法?

C中的宏生成宏?

我想让C预处理器为我生成宏(即,我只使用C99)。 我写了一个宏 #define make_macro(in) 当我放 make_macro(name1) make_macro(name2) 稍后在代码中,它将扩展为 #define name1(…) name1_fn(name1_info, __VA_ARGS__) #define name2(…) name2_fn(name2_info, __VA_ARGS__) 然后我就可以使用name1和name2作为(宏实现的)函数。 我认为我在两个步骤中都使用了宏:使用宏来重复填充模板是有意义的,并且除了通过宏之外,可变参数处理将不起作用。 那么占位符是做什么的呢? 在这一点上,我开始相信它在C99中是不可能的,但也许我错过了语法的一些细节。

C中的Static,define和const

我已经读过,当每次调用函数时不希望变量值改变/初始化时,静态变量在函数内部使用。 但是如何在“main”之前在主程序中定义变量static,例如 #include static double m = 30000; int main(void) { value = m * 2 + 3; } 这里变量m具有一个常数值,以后不会在主程序中修改。 在同一思路中,它有什么不同,而不是使用静态定义: const double m = 30000; 要么 #define m 30000 //m or M 然后确保在主代码中使用双重操作,以便将m转换为正确的数据类型。

是不是有语法错误? 应该是printf(“一个”,两个和“”%s。\ n“,”三个“); 是有效的代码?

看看这段代码: #include #define _ONE “one” #define _TWO_AND “, two and ” int main() { const char THREE[6] = “three” ; printf(_ONE _TWO_AND “%s.\n”, THREE ); return 0; } printf有效: printf(“one” “, two and ” “%s.\n”, “three” ); 输出是: 一,二,三。 编译此代码后, gcc既没有错误也没有警告消息。 gcc编译器是否应该以这种方式工作,还是一个bug?

何时可以省略宏中参数的括号?

通常我常常觉得围绕宏定义中的参数的一些括号是多余的。 把一切都括起来太不方便了。 如果我可以保证参数不需要括号,我可以省略括号吗? 或者强烈建议将它们括起来? 我写的时候想出了这个问题: #define SWAP_REAL(a, b, temp) do{double temp = a; a = b; b= temp;}while(0) 我认为如果参数在宏中显示为l值,则可以省略括号,因为这意味着参数出现时没有其他操作。 我的理由是: 赋值符号的关联优先级仅高于逗号。 您不能将编译器混淆为认为您的参数是带有逗号的表达式。 例如, SWAP(a, b, b)将不会被成功解释为 do{double temp = a, b; a, b = b; b= temp;}while(0) 哪个可以通过编译。 我对吗? 任何人都可以给我一个反例吗? 在以下示例中, #define ADD(a, b) (a += (b)) 我认为这个论点不需要用括号括起来。 在这种特殊情况下,既不需要参数b ,对吗? @JaredPar: #include #define ADD(a, b) […]

重载C宏

有没有更好的方法来“重载”像这样的宏? 我需要一个接受各种参数的宏。 #define DEBUG_TRACE_1(p1) std::string p[] = {p1}; log _log(__FUNCTION__, p, 1) #define DEBUG_TRACE_2(p1, p2) std::string p[] = {p1, p2}; log _log(__FUNCTION__, p, 2) #define DEBUG_TRACE_3(p1, p2, p3) std::string p[] = {p1, p2, p3}; log _log(__FUNCTION__, p, 3) #define DEBUG_TRACE_4(p1, p2, p3, p4) std::string p[] = {p1, p2, p3, p4}; log _log(__FUNCTION__, p, 4) #define […]

编译时的偏移量

有没有办法在编译时找到结构成员的偏移量? 我希望创建一个包含结构成员偏移量的常量。 在以下代码中, offsetof()宏在第一个printf语句中起作用。 但是,在第10行中使用声明ofs产生错误: “无法解析’ – >’运算符作为常量表达式”。 这样做还有其他方法吗? struct MyStruct { unsigned long lw; unsigned char c[5]; int i; int j; unsigned long last; }; const int ofs = offsetof(struct MyStruct, i); // This line in error int main(void) { printf(“Offset of c = %d.\n”, offsetof(struct MyStruct, c) ); printf(“Offset of i = %d.\n”, […]

为什么C / C ++预处理器在这里添加空格?

我的预处理器有一个小问题困扰我,我在文档/预处理器/语言规范中找不到任何解释。 #define booboo() aaa booboo()bbb booboo().bbb 被预处理成: aaa bbb <— why is space added here aaa.bbb 处理三字符,连续行和注释后,预处理器在预处理程序指令上工作,并将输入分为预处理标记和空格。 booboo的替换列表包含一个pp标记,它是标识符’aaa’。 booboo()bbb分为pp-tokens:’booboo’,’(’,’)’,’bbb’。 ‘booboo’,’(’,’)’的序列被识别为function宏调用,它应该扩展为’aaa’,输出中的imho应该看起来像’aaabbb’。 我说过看起来像是 – 对于人类 – 它看起来像一个标记,而编译器将获得2个令牌’aaa’和’bbb’,因为没有使用允许pp-token连接的’##’运算符。 当’booboo()。bbb’导致’aaa.bbb’没有空格时,为什么/什么规则使cpp(c预处理器)在’aaa’和’bbb’之间放置额外的空格? 这是因为cpp试图使输出(主要是针对人类)产生不连续性吗? 人类无法分辨出’aaabbb’是由2个令牌组成的,因为它只能看到令牌的拼写。 我对吗? 我已经阅读了关于预处理器的C99文档和cpp的gcc文档。 我什么也看不见。 如果我是对的,我们在这里有类似的情况: #define baba() + baba()+ baba()- 结果是: + + +- 否则(如果’++’是输出)它会看起来像’++’令牌,但会有2个令牌’+’和’+’。 是否与’##’运算符一样,cpp检查串联是否产生有效令牌,但是在显示的情况下想要阻止人类执行串联? ‘+ – ‘不含糊,因此没有添加空格

何时在C中使用类似函数的宏

今晚我正在阅读一些用C语言编写的代码,文件顶部是类似函数的宏HASH: #define HASH(fp) (((unsigned long)fp)%NHASH) 这让我想知道,为什么有人会选择使用类似函数的宏来实现这种函数,而不是将它作为常规的vanilla C函数实现? 每种实施的优缺点是什么? 谢谢你!

C宏 – 动态#include

我试图弄清楚如何使用GCC为#include语句构建变量字符串。 我的想法是,对于我编写的每个源模块,我希望包含一个动态生成的C源头,它是在构建过程的早期创建的。 生成此文件不是问题。 不幸的是,包括它在内。 到目前为止我所拥有的是(identities.h): // identities.h # define PASTER2(str) #str # define PASTER(str) PASTER2(str ## .iden) # define EVALUATOR(x) PASTER(x) # define IDENTITIES_FILE EVALUATOR(__FILE__) # include IDENTITIES_FILE 理想情况下,这将使用(main.c): //main.c # include “identities.h” int main() {return 0;} 在编译之前,预处理器将在一次传递中扩展为: //main.c (preprocessed) # include “main.c.iden” int main() {return 0;} 我正在使用的两个间接级别(PASTER和EVALUATOR)是这篇文章的结果。 不幸的是,这不起作用,我留下了错误: obj/win32/dbg/main.o In file included from main.c:1:0: […]