在编译时分配静态数组的宏

huangapple go评论68阅读模式
英文:

Macro to allocate a static array in compile time

问题

以下是代码部分的翻译:

typedef struct Node
{
    struct Node* prev;
    struct Node* next;  
    bool allocated;
    void* object;
} node_t;

#define ALLOC(size) { node_t vec[size]; return &vec[0] } 

#define list_const_func_pointers(max_list_size) \
{ \
    .maximum_list_size = max_list_size, \
    .vectorLL = ALLOC(max_list_size), \
    .init = init_linked_list, \
    .my_st_malloc = my_static_malloc \
}

struct static_doublyll_t
{
    node_t* head;
    node_t* last;
    int32_t list_size; 
    const uint32_t maximum_list_size; 
    node_t* vectorLL; 
    
    void (*const init)(static_doublyll_t*);
    
    node_t* (*const my_st_malloc)(static_doublyll_t* l);
    
    static_doublyll_t* this_pointer; 
};

// Driver code:

#define list_size 20

static static_doublyll_t list = list_const_func_pointers(list_size);

希望这对你有所帮助。如果你有任何其他问题,欢迎提出。

英文:

Is there a way to allocate a static array in compile time ?

Example:

    typedef struct Node
    {
    	struct Node* prev;
    	struct Node* next;  		       
    	bool allocated;     
    	void* object;
    }node_t;

    #define ALLOC( size ) { node_t vec[size]; return &vec[0] }     

    #define list_const_func_pointers(max_list_size)  \
    {                                                \
        .maximum_list_size = max_list_size,          \
	    .vectorLL = ALLOC( max_list_size ),          \
    	.init = init_linked_list,                    \
	    .my_st_malloc = my_static_malloc             \
    }
   
    struct static_doublyll_t
    {
        node_t* head;
        node_t* last;
        int32_t list_size;  // "actual list size"
    	const uint32_t maximum_list_size;  // Tamanho do array de node_t alocado estaticamente.    
    	node_t* vectorLL;  // Aponta para uma array de node_t alocado estaticamente.
    	
    	void (*const init)(static_doublyll_t*);
    		
    	node_t* (*const my_st_malloc)(static_doublyll_t* l);
    	
    	static_doublyll_t* this_pointer;  // unnecessary because "recursion problem".	
    };

// Driver code:

    #define list_size 20
    
    static static_doublyll_t list = list_const_func_pointers(list_size); // init the const "variables".

Notes:

  • I need that the compiler return unique memory blocks (statically allocated at compile time) on each macro call.

  • This macro in the above example is what I need to work:

      #define ALLOC( size ) { node_t vec[size]; return &vec[0] }"
    

答案1

得分: 1

typedef struct Node
{
    struct Node* prev;
    struct Node* next;                 
    bool allocated;     
    void* object;
} node_t;


#define DECLARE(name, max_list_size)            
static node_t node_t##name[max_list_size];     
struct static_doublyll_t name =                 
{                                               
    .maximum_list_size = max_list_size,         
    .vectorLL = node_t##name,                  
}
   
struct static_doublyll_t
{
    node_t* head;
    node_t* last;
    int32_t list_size;  
    const uint32_t maximum_list_size;  
    node_t* vectorLL;  
};

// Driver code:

#define list_size 20

DECLARE(list, list_size); 
英文:

I would suggest something more simple.

    typedef struct Node
    {
        struct Node* prev;
        struct Node* next;                 
        bool allocated;     
        void* object;
    }node_t;


    #define DECLARE(name, max_list_size)            \
    static node_t node_t##name[max_list_size];     \
    struct static_doublyll_t name =                 \
    {                                               \
        .maximum_list_size = max_list_size,         \
        .vectorLL = node_t##name,                  \
    }
   
    struct static_doublyll_t
    {
        node_t* head;
        node_t* last;
        int32_t list_size;  // "actual list size"
        const uint32_t maximum_list_size;  // Tamanho do array de node_t alocado estaticamente.    
        node_t* vectorLL;  // Aponta para uma array de node_t alocado estaticamente.
    };

// Driver code:

    #define list_size 20
    
    DECLARE(list, list_size); 

答案2

得分: 1

我需要编译器在每次宏调用时返回唯一的内存块(在编译时静态分配)。

宏不像函数一样“调用”,它们不会“返回”任何内容。编译器会在编译时扩展宏调用,并将结果编译成C代码,放在周围C代码的上下文中。

您在一个需要将宏扩展为数组或指针类型表达式的上下文中使用宏。在这种情况下,您最好使用复合文字:

#define ALLOC(size) ( (node_t []) { [size - 1] = {0} } )

这将仅在文件范围之外(即在任何函数之外)生成具有静态存储期的数组。从示例代码中不太清楚这是否符合您的需求。不过,我观察到,您所描述的另一种情况可能在具有静态存储期的本地对象的初始化器中出现,如果是这种情况,您可以考虑将其移到函数之外。

请注意,根据您的描述,对某个函数的每次调用都需要提供单独的数组,或者size参数在每次调用时不是编译时常量的情况都没有意义。这些情况通常需要动态分配。

英文:

> I need that the compiler return unique memory blocks(statically allocated at compile time) on each macro call.

Macros are not "called" in the same sense as functions, and they do not "return" anything. The compiler expands macro invocations at compile time, and compiles the result as C code, in the context of the surrounding C code.

You are using the macro in a context where it needs to expand to an expression of array or pointer type. Your best bet for that would be to use a compound literal:

#define ALLOC(size) ( (node_t []) { [size - 1] = {0} } )

That will produce an array with static storage duration only at file scope (that is, outside any function). It's unclear from the example code whether that would serve your purpose. I observe, however, that the only other context where what you describe could make sense would be in the initializer of a local object with static storage duration, and if that's what you have then you could consider just moving that out of its function.

Note well that what you describe does not make any sense at all for something that needs to provide a separate array on each call to some function, nor where the size parameter is not a compile-time constant at each invocation. Those kinds of things generally demand dynamic allocation.

huangapple
  • 本文由 发表于 2023年2月18日 08:57:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75490500.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定