I have implemented an array based pseudo-generic stack in C using macros. The code works fine for all data types. Is it a good idea to implement such a data structure using macros?
array_stack.h
#ifndef ARRAY_STACK_H
#define ARRAY_STACK_H
#include<stdlib.h>
#define array_stack(type) struct{size_t _size;size_t _capacity;type*_arr;}
#define stack_init(stack) do{\
stack._capacity=1;\
stack._size=0;\
stack._arr=calloc(stack._capacity,sizeof(*stack._arr));\
}while(0)
#define stack_push(stack,data) do{\
if(stack._size==stack._capacity)\
{\
stack._capacity*=2;\
void*new_array=realloc(stack._arr,stack._capacity*sizeof(*stack._arr));\
stack._arr=new_array;\
}\
stack._arr[stack._size]=data;\
stack._size++;\
\
}while(0)
#define stack_pop(stack) if(stack._size!=0) stack._size--
#define stack_top(stack) (stack._size>0) ? stack._arr[stack._size-1] : *stack._arr //returns address of array if stack is empty
#define stack_empty(stack) (stack._size==0)
#define stack_length(stack) stack._size
#endif
Usage in main.c
#include<stdio.h>
#include<stdlib.h>
#include"array_stack.h"
#include<string.h>
int main(int argc,char**argv)
{
array_stack(char)chars;
array_stack(double)nums;
stack_init(chars);
stack_init(nums);
const char*text="AzZbTyU";
for (size_t i = 0; i < strlen(text); i++)
stack_push(chars,text[i]);
stack_push(nums,3.14);
stack_push(nums,6.67);
stack_push(nums,6.25);
stack_push(nums,0.00019);
stack_push(nums,22.2222);
printf("Printing character stack: ");
while(!stack_empty(chars))
{
printf("%c ",stack_top(chars));
stack_pop(chars);
}
printf("\n");
printf("Printing double stack: ");
while(!stack_empty(nums))
{
printf("%lf ",stack_top(nums));
stack_pop(nums);
}
printf("\n");
return 0;
}
_prefixes with member names? \$\endgroup\$_too. "All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use, except those identifiers which are lexically identical to keywords. — All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces." I hope the general application or your scheme and the C standard to not collide. Instead of prefixing_to show it is private, perhaps use"private_"to make it more obvious. \$\endgroup\$