OnlyVery Nice.
Only small stuff
1 Why (float) in size_t new_slots = (float)stack->slots * stack->multiplier;?
Given
sizeof size_tmay not equalsizeof float, suggest grouping like types instructtypedef struct { void *content; size_t element_size; ... size_t expansion_amount; float multiplier; } Stack;Since
new_stack()may return NULL, note the other main functions are not protected from dereferencing NULL. Protection is not a hard requirement here - more about design philosophy about should main level routine have NULL protection? Your call.
Why
(float)insize_t new_slots = (float)stack->slots * stack->multiplier;?Given
sizeof size_tmay not equalsizeof float, suggest grouping like types instructtypedef struct { void *content; size_t element_size; ... size_t expansion_amount; float multiplier; } Stack;Since
new_stack()may return NULL, note the other main functions are not protected from dereferencing NULL. Protection is not a hard requirement here - more about design philosophy about should main level routine have NULL protection? Your call.Minor: Could use a float in the define to emphasize the value will be used as a
float.
#define MULTIPLIER (1.00f)(I assume your header is at global scope.) Since
typedef struct { ... } Stackis only used by an application as a pointer, could use an anonymous pointer to insure information hiding.The defines may be useful to an application as defaults parameters. There, they could appear at global scope, so use less generic names.
#define Stack_MINIMUM_ELEMENT_SIZE (1) #define Stack_MULTIPLIER (1.0f) #define Stack_EXPANSION_AMOUNT (8)