我想强制预处理器为我做一些自动代码生成.我不需要太多:只是一个包含另一个for循环的简单for循环.[1]
我已经阅读了所有关于宏观扩展的内容,并且在蓝色涂料出现时不再傻笑.在美好的一天,我甚至可以解释为什么需要多层宏来生成带有标记粘贴的函数名称.我实际上已经让for-loop工作了.但是当涉及在循环中放置一个循环时,我会减少随机使用DEFER,EVAL和OBSTRUCT,并希望最好.
我不会被理智的召唤吓倒.我确实想用标准的C预处理器来做这件事.我保证无论结果如何,我,我的雇主和我的继承人都不会因技术弊端而起诉你.我保证如果没有适当的安全眼镜,我不会允许任何人维护代码,甚至不能查看代码.如果你愿意,假装我只是在考虑理论上的兴趣.或者我唯一的另一种选择是使用M4:因为如果CPP中的递归宏是变态的,那么M4肯定是全鸡.
我发现的最好的参考资料是一个有9年历史的Usenet线程:http: //comp.std.c.narkive.com/5WbJfCof/double-cpp-expansion
它开始偏离主题,在语气上有点小气和好斗,并且是我的头脑.但我认为我寻求的答案就在那里.
下一个最好的是CPP滥用标题的文档,称为Cloak:https: //github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
它需要一种不同的迭代方法,或许可以满足我的需求.但它也是一个很好的概述.
这里有一些简短的代码来显示我被卡住的地方.
repeat.h:
#define REPEAT(macro, times, start_n, next_func, next_arg, macro_args...) \
_REPEAT_ ## times(macro, start_n, next_func, next_arg, ## macro_args)
#define REPEAT_ADD_ONE(macro, times, start_n, macro_args... ) \
REPEAT(macro, times, start_n, _REPEAT_ADD_ONE, 0, ## macro_args)
#define _REPEAT_ADD_ONE(n, ignore...) _REPEAT_ADD_ONE_ ## n
#define _REPEAT_0(args...) /* empty */
#define _REPEAT_1(macro, n, func, i, args...) macro(n, ## args)
#define _REPEAT_2(m, n, f, i, a...) m(n, ## a); _REPEAT_1(m, f(n, i), f, i, ## …Run Code Online (Sandbox Code Playgroud) 我的结构如下
typedef struct
{
int a;
int b;
int c;
} my_struct;
Run Code Online (Sandbox Code Playgroud)
在另一个文件中,我声明了这种my_struct类型的变量,如下所示.
my_struct strct_arr[MAX];
Run Code Online (Sandbox Code Playgroud)
MAX宏在哪里是可配置值,是18的倍数(18或36或54等等......它可能达到18*n次).
我必须用{0xff,0,0}初始化结构.那么,如何my_struct strct_arr[MAX];使用我的初始值初始化整个结构数组而不使用任何类型的循环.
我期待输出如下:
my_struct strct_arr[MAX]={
{0xff,0,0},
{0xff,0,0},
{0xff,0,0},
{0xff,0,0},
…
};
Run Code Online (Sandbox Code Playgroud)
但是,如果不知道MAX价值,如何初始化它?
我如何编写一个像这样使用的宏(用于 gcc):
CREATE_STRUCT(my_struct1,foo);
CREATE_STRUCT(my_struct2,foo,bar);
Run Code Online (Sandbox Code Playgroud)
并扩展到
struct my_struct1 {
std::string foo;
};
struct my_struct2 {
std::string foo;
std::string bar;
};
Run Code Online (Sandbox Code Playgroud)
?
我当然需要不同数量的成员的灵活性,但对我来说已经很小的数量就可以了(比如 4 或 5)。
我发现了几个相关的问题,例如this和this,但是在尝试将这种神秘的宏魔法应用于这个问题时,我完全迷失了。
PS:我知道如何编写 5 个宏(每个参数一个)来完成这项工作,所以实际上问题是:是否有一种“简单”的方法来编写一个可以完成这项工作的可变参数宏?另一方面,我将向结构中添加更多内容,因此将所有内容放在一个地方会节省大量样板。
考虑以下GLSL函数:
float Pow3 (const in float f) {
return f * f * f;
}
float Pow4 (const in float f) {
return f * f * f * f;
}
float Pow5 (const in float f) {
return f * f * f * f * f;
}
Run Code Online (Sandbox Code Playgroud)
... 等等.有没有一种方法,以#定义一个宏GLSL可以产生ñ乘法-OF- ˚F逐本身在编译的时候,不使用内置GLSL POW()当然功能?
我见过类似的线程,但是,不知道如何将解决方案完全应用到我的案例中.我的问题是我有一组用例可以说'A','B','C',当输入传递时需要执行某些命令(2个用例是输入)是列出的任何2个用例.例如:
switch(input1)
{
case A:
break;
case B:
break;
case C:
break;
}
Run Code Online (Sandbox Code Playgroud)
在每种情况下,我将不得不检查输入2,因此,最终的代码可能看起来像
switch(input1)
{
case A:
{
switch(input2):
case B:
break;
case c:
break;
}
case B:
{
switch(input2):
case A:
break;
case c:
break;
}
....
}
Run Code Online (Sandbox Code Playgroud)
我正在考虑使用(pair,command)的地图并删除这个开关案例,但有没有其他更好的解决方案或设计问题来解决这个问题?
我尝试使用下面的代码来跟踪使用新变量的各个循环的迭代ForloopCountM.该代码适用于循环内的循环和循环循环.但是Macro在以下两种情况下都失败了,我需要帮助如何解决这个问题并跟踪迭代次数.
void forloopTrace(int ForloopCount)
{
if( ForloopCount==50)
printf("Invalid \n");
}
#define CONCAT_IMPL( x, y ) x##y
#define MACRO_CONCAT( x, y ) CONCAT_IMPL( x, y )
#define FORlOOPCOUNTM MACRO_CONCAT(ForloopCountM,__LINE__)
#define for(args...)\
int FORlOOPCOUNTM=0;\
for(args,FORlOOPCOUNTM++,forloopTrace(FORlOOPCOUNTM))\
int main()
{
int i,j,x,y;
j=100;
y=200;
for(i=0;i<j;i) //works fine
{
i++;
for(x=0;x<y;x) //works fine
x++;
}
if(i>0)
for(;i>0;) //ERROR
i--;
for(;;) //Error
{
i++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud) I'm trying to write a macro which simplifies setting multiple bits in an integer. This commonly occurs in microcontroller code when initializing configuration registers. For example, one might configure an 8-bit timer by setting 3 bits in the register TCCR0A like this:
// WGM01, WGM00 and COM0A1 are constants between 0 and 7
// There are hundreds of these constants defined in avr-libc
TCCR0A |= (1<<WGM01) | (1<<WGM00) | (1<<COM0A1);
// Another way to write this:
#define _BV(bit) (1 << …Run Code Online (Sandbox Code Playgroud) 我发现这个宏#define TIMES(x) for(int i1=0;i1<x;i1++)非常实用,可以缩短代码文本.但是当我有嵌套循环时,我不知道如何编写这样的宏,甚至我不知道是否可能.这个想法如下.是否可以编写此代码
for(int i1=0;i1<5;i1++)
for(int i2=0;i2<3;i2++)
for (int i3=0;i3<7;i3++)
/* many nested `for` loops */
{
/* some code, for example to print an array printf("%d \n",a[i1][i2][i3]) */
}
Run Code Online (Sandbox Code Playgroud)
如
TIMES(5) TIMES(3) TIMES(7) ....
{
/* some code, for example to print an array printf("%d \n",a[i1][i2][i3]) */
}
Run Code Online (Sandbox Code Playgroud)
用一种"递归"宏来检测所有TIMES并通过for循环替换它们与i1,i2,i3,... i'n'循环计数器?
我需要做一个循环,我将这个简单的反射示例转换为:
std::string mystring[3] = {{"mystring[0]"},{"mystring[1]"},{"mystring[2]"}};
Run Code Online (Sandbox Code Playgroud)
为更长的阵列更加可管理的形式.解决方案听起来像我应该使用带循环的宏或递归.但是,宏不支持循环或递归!
如何创建一个宏来随意处理这个问题?
#define NAME_OBJ(type, name, size)
Run Code Online (Sandbox Code Playgroud) 我是 C 新手,我习惯用 python 编写代码,我通常会打印太多变量和文本来测试我的代码,而 printf 语句有时很烦人。我想用 c 编写一个函数,它的工作原理与 python 中的打印函数完全一样。
我在编写函数时面临两个问题。
print(12); print("hello"); print(123.12)不应引发错误。到目前为止我做了什么
我找到了使用 <stdarg.h> 获取 n 个参数的解决方案,但我必须指定第一个参数的数据类型,这不是我想要的。
“通用选择”宏可用于对传递的不同数据类型的参数调用不同的函数,但不确定如何完成,这是我用于参考的链接。