我正在用C++创建一个宏来声明一个变量并为它赋值.根据宏的使用方式,宏的第二次出现可以覆盖第一个变量的值.例如:
#define MY_MACRO int my_variable_[random-number-here] = getCurrentTime();
Run Code Online (Sandbox Code Playgroud)
使用它的另一个动机是避免为变量选择某个名称,以使其与开发人员最终使用宏选择的名称相同.
有没有办法在C++中的宏内生成随机变量名?
- 编辑 -
我的意思是独特但也是随机的,一旦我可以在一个块中使用我的宏两次,在这种情况下,它将生成如下:
int unique_variable_name;
...
int unique_variable_name;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,为了唯一,必须随机生成两个变量名.
我已经看到使用gcc __section__属性(特别是在Linux内核中)将数据(通常是函数指针)收集到自定义ELF部分中.如何检索和使用这些自定义部分中的"东西"?
我想定义一组事物,比如事件处理程序.这个数组的内容在编译时是完全已知的,但是在多个编译单元之间定义,分布在多个相当分离的库中,至少直到最终(静态)链接.我也希望保持这种方式 - 因此添加或删除编译单元也将自动管理事件处理程序,而无需修改事件处理程序的中央列表.
这是我想做的一个例子(但不起作用).
central.h:
typedef void (*callback_t)(void);
callback_t callbacks[];
Run Code Online (Sandbox Code Playgroud)
central.c:
#include "central.h"
void do_callbacks(void) {
int i;
for (i = 0; i < sizeof(callbacks) / sizeof(*callbacks); ++i)
callbacks[i]();
}
Run Code Online (Sandbox Code Playgroud)
foo.c的:
#include "central.h"
void callback_foo(void) { }
callback_t callbacks[] = {
&callback_foo
};
Run Code Online (Sandbox Code Playgroud)
bar.c:
#include "central.h"
void callback_bar(void) { }
callback_t callbacks[] = {
&callback_bar
};
Run Code Online (Sandbox Code Playgroud)
我想要发生的是获得一个callbacks包含两个元素的数组:&callback_foo和&callback_bar.使用上面的代码,显然有两个问题:
callbacks阵列定义了多次.sizeof(callbacks)编译时不知道central.c.在我看来,第一点可以通过链接器合并两个callbacks符号而不是抛出错误(可能通过变量的某些属性)来解决,但我不确定是否有类似的东西.即使有,问题的大小也应该以某种方式解决.
我意识到这个问题的一个常见解决方案是只有一个"注册"回调的启动函数或构造函数.但是,我只能看到两种实现方法:
由于我在内存有限的微控制器平台(Arduino)上运行,因此这些方法都不适合我.鉴于数组的全部内容在编译时是已知的,我希望有一种让编译器也能看到它的方法.
我已经找到了这个和 …
在C中,与C++不同,必须命名函数定义的所有参数.
我创建了以下宏,而不是使用(void)a或公开使用来撤销"未使用的参数"错误__attribute__((unused)):
#define UNUSED2(var, uniq) UNUSED_ ## line ## var __attribute((unused))
// squash unused variable warnings, can it be done without var?
#define UNUSED(var) UNUSED2(var, __func__)
Run Code Online (Sandbox Code Playgroud)
像这样使用
void blah(char const *UNUSED(path)) {}
Run Code Online (Sandbox Code Playgroud)
有没有一些方法,我可以保证一个独特的"虚拟"变量名(显然LINE并__func__不能削减它),或忽视的名字在所有未使用的变量?
使用的最终代码可在此处获得.
#ifdef __cplusplus
// C++ allows you to omit parameter names if they're unused
# define OMIT_PARAM
#else
// A variable name must be provided in C, so make one up and mark it unused
# …Run Code Online (Sandbox Code Playgroud) 我有多个头文件,每个头文件都必须在数组中附加一个数字来注册它的函数.
目前我在每个头文件中都有一个具有唯一名称的函数,在程序文件中我需要在一个组合函数中调用所有这些函数.
int register1() { return 100; }; //in header1.h
int register2() { return 200; }; //in header2.h
int register3() { return 300; }; //in header3.h
int register4() { return 400; }; //in header4.h
int registered[] = {register1(),register2(),register3(),register4()}; //main.c
Run Code Online (Sandbox Code Playgroud)
但这很不方便,因为我需要在添加或删除头文件时在两个地方进行修改.最好只修改头文件.我正在考虑预处理器定义,所以在每个头文件中我可以使用类似的东西:
#define Registered Registered,100 // header1.h
#define Registered Registered,200 // header2.h
int registered[] = {Registered}; // main.c
Run Code Online (Sandbox Code Playgroud)
但这当然不会编译,因为新的定义重新定义旧的定义.那么有没有办法追加一个定义?或者在不修改两个文件的情况下将数字附加到数组的其他方法?
这是C,而不是C++,否则我会使用一个带有构造函数的类实例,它只会写入一个数组.有些想法:
struct __header1{ __header1() {
global_array[global_array_ptr++] = 100;
} } __header1_inst;
Run Code Online (Sandbox Code Playgroud)
然后将其转换为一个漂亮的宏:
#define register(hdr, func) struct __header##hdr{ __header##hdr() { \
global_array[global_array_ptr++] = func; …Run Code Online (Sandbox Code Playgroud) 我在C中有这个POC,它在一个自定义部分中保存了一些结构,然后迭代这些结构,显示它们的内容.
#include <stdio.h>
char a, b, c;
struct counter_info {
int counter;
char *name;
} __attribute__((packed));
#define __PUT_STUFF_IN_SECTION(_name) \
do{ \
static struct counter_info __counter_info_##_name \
__attribute((__section__("counters"))) \
__attribute((__used__)) = { \
.name = #_name, \
.counter = 0, \
}; \
}while(0)
extern struct counter_info __start_counters;
extern struct counter_info __stop_counters;
int main(int argc, char **argv){
printf("Start %p\n", &__start_counters);
__PUT_STUFF_IN_SECTION(a);
__PUT_STUFF_IN_SECTION(b);
__PUT_STUFF_IN_SECTION(c);
struct counter_info *iter = &__start_counters;
for(; iter < &__stop_counters; ++iter){
printf("Name: %s | Counter: %d.\n", iter->name, iter->counter);
} …Run Code Online (Sandbox Code Playgroud)