Tag:

具有宏的类型安全的通用容器

我正在尝试使用宏在C中创建一个类型安全的通用链表。 它应该与模板在C ++中的工作方式类似。 例如, LIST(int) *list = LIST_CREATE(int); 我的第一次尝试是#define LIST(TYPE) (我上面使用的宏)来定义struct _List_##TYPE {…} 。 但是,这不起作用,因为每次我声明一个新列表时都会重新定义结构。 我通过这样做解决了这个问题: /* You would first have to use this macro, which will define the `struct _List_##TYPE`… */ DEFINE_LIST(int); int main(void) { /* … And this macro would just be an alias for the struct, it wouldn’t actually define it. */ […]

如何定义描述内存位置的宏?

变量位于存储器中的地址0x10000处。 如何定义一个宏,以便写入该宏写入该内存位置?

预处理器:将字符串连接到__VA_ARGS__中的每个参数

我想将一个字符串化的宏参数附加到可变参数宏中的每个元素。 我想我知道我需要什么,但我还没有想出一个有效的解决方案。 鉴于可变宏,如: #define FIELD_DECLARATION(NAME, OTHER_FIELD, …) FIELD_DECLARATION(First, Thing) FIELD_DECLARATION(Second, Thing, Thing, Nothing) 我想生成: field_First = {ThingArg}; field_Second = {ThingArg, ThingArg, NothingArg}; 我想我需要的是递归地继续扩展__VA_ARGS__直到它没有元素,并在进行扩展时附加”Arg” 。 最后,将结果传递给另一个可变参数宏,该宏生成以逗号分隔的参数列表。 我试过这个,这是行不通的(也不是我所描述的): #define UNPACK_VA_1(A1) A1 ## Arg #define UNPACK_VA_2(A1, A2) UNPACK_VA_1(A1), UNPACK_VA_1(A2) #define UNPACK_VA_3(A1, A2, A3) UNPACK_VA_2(A1, A2), UNPACK_VA_1(A3) #define UNPACK_VA_4(A1, A2, A3, A4) UNPACK_VA_2(A1, A2), UNPACK_VA_2(A3, A4) #define UNPACK_VA(…) UNPACK_VA_4(__VA_ARGS__) […]

C预处理器:尽早评估宏

请考虑以下设置: 啊 #define A 5 #define BA #undef A #define A 3 AC #include “ah” #include int main() { printf(“%d\n”, B); return 0; } 虽然这非常合理地打印3,有没有办法让它打印5,即在第二行啊已经替换为5的A?

C宏启用和禁用代码function

我之前使用过代码库,它有一个宏系统,用于启用和禁用代码段。 它看起来像下面这样: #define IN_USE X #define NOT_IN_USE _ #if defined( WIN32 ) #define FEATURE_A IN_USE #define FEATURE_B IN_USE #define FEATURE_C NOT_IN_USE #elif defined( OSX ) #define FEATURE_A NOT_IN_USE #define FEATURE_B NOT_IN_USE #define FEATURE_C IN_USE #else #define FEATURE_A NOT_IN_USE #define FEATURE_B NOT_IN_USE #define FEATURE_C NOT_IN_USE #endif 然后,function的代码如下所示: void DoFeatures() { #if USING( FEATURE_A ) // Feature […]

如何知道另一个函数

我想知道是否有任何方法可以知道当前执行的函数在哪里被调用,这是在什么文件和行中。 我正在使用C语言,我正在寻找类似于__FUNCTION __,__LINE__或__FILE__宏的东西。

C预处理器和操作顺序

我正在学习C,但我不明白这一点: #define square(x) x*x a = square(2+3) //a = 11 当这个运行时,为什么最终会成为11 ?

使用etrace在C ++中按时间顺序跟踪函数调用

背景: 我有一个很大的模拟工具,我需要了解它的逻辑行为。 为了做到这一点,如果我有函数调用的时间顺序,我将得到的大部分帮助,用于最小的工作示例。 我在网上找到了很多工具,比如CygProfiler和etrace 。 在找到解决方案时,我开始变得非常痛苦,我开始遵循使用调试器“步入”的最疯狂的解决方案。 如果你有一个小程序但不是一个完整的模拟工具,这是一个很好的选择。 问题: 我面临的一个问题是上述解决方案最初是针对C ,它们在编译时会生成一个静态文件( *.o )。 另一方面,模拟工具生成共享库( .so )。 我对较低级别的东西知之甚少,所以当我尝试链接它们时,我似乎失败了。 我专门查看了etrace 文档 ,它说: 要了解如何修改ptrace.c以使用动态库,请查看example2目录。 这里的源代码也创建了一个独立的可执行文件,但PTRACE_REFERENCE_FUNCTION宏的定义与动态库一样。 如果查看repo, example和example2文件夹中的文件没有区别。 在example2只有一个额外的.h文件。 另一方面,如果你看一下src/ptrace.c那就说: 在动态库上使用ptrace时,必须将PTRACE_REFERENCE_FUNCTION宏设置为库中函数的名称。 加载时此函数的地址将是输出到跟踪文件的第一行,并允许将其他入口和出口指针转换为其符号名称。 您可以将宏PTRACE_INCLUDE设置为该函数可访问此源文件所需的任何#include指令。 稍微低于评论代码: /* When using ptrace on a dynamic library, the following must be defined: #include “any files needed for PTRACE_REFERENCE_FUNCTION” #define PTRACE_REFERENCE_FUNCTION functionName `*/ 题: 本质上问题如下:如何在动态库中使用etrace ? […]

如何使用CPP预处理器编写递归for循环“重复”宏来生成C代码?

我想强制预处理器为我做一些自动代码生成。 我不需要太多:只是一个包含另一个for循环的简单for循环。[1] 我已经阅读了所有关于宏观扩展的内容,并且在蓝色涂料出现时不再傻笑。 在美好的一天,我甚至可以解释为什么需要多层宏来生成带有标记粘贴的函数名称。 我实际上已经让for-loop工作了。 但是当把循环放在一个循环中时,我会减少随机地使用DEFER,EVAL和OBSTRUCT并且希望最好。 我不会被理智的召唤吓倒。 我确实想用标准的C预处理器来做这件事。 我保证无论结果如何,我,我的雇主和我的inheritance人都不会因技术弊端而起诉你。 我保证如果没有适当的安全眼镜,我不会允许任何人维护代码,甚至不能查看代码。 如果你愿意,假装我只是在考虑理论上的兴趣。 或者我唯一的另一种选择是使用M4:因为如果CPP中的递归宏是变态的,那么M4肯定是整只鸡。 我发现的最好的参考资料是一个有9年历史的Usenet线程: http : //comp.std.c.narkive.com/5WbJfCof/double-cpp-expansion 它开始偏离主题,在语气方面有些小而且好斗,而且是我的头脑。 但我认为我寻求的答案就在那里。 接下来最好的是一个名为Cloak的CPP滥用标题的文档: 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, ## […]

C预处理器:如何创建字符文字?

出于好奇,我想知道是否可以定义一个可以将其参数转换为字符文字的宏: switch(getchar()) { case MYMACRO(A): printf(“Received A\n”); break; case MYMACRO(a): printf(“Received a\n”); break; case MYMACRO(!): printf(“Received an exclamation mark\n”); break; default: printf(“Neither a nor A nor !\n”); break; } 我头脑中有两种可能的解决方案: 枚举所有字符 #define LITERAL_a ‘a’ #define LITERAL_b ‘b’ … #define MYMACRO(x) LITERAL_ ## x 它不适用于MYMACRO(!)因为! 不是C标识符的有效组件。 将参数转换为字符串文字 #define MYMACRO(x) #x [0] 它涉及指针取消引用,并且在诸如案例标签的地方无效。 我不是要求一种方法来“改进”上面的switch语句本身。 这只是一个玩具的例子。 重复。 这只是一个玩具的例子。