-
.c file and .h file
I create(nothing serious here) a .c file and a .h file and I want to know if I set them up correctly. I want to expose the struct and its elements(struct slice) and the function createSlice. I want everything else to be not be available.
slice.h
Code:
#include <stdlib.h>
#ifndef SLICE_HH
#define SLICE_HH
struct slice
{
size_t pos;
size_t length;
void (*free_slice)(const struct slice *);
void(*append)(struct slice *, unsigned int);
unsigned int (*get)(const struct slice *, size_t);
void (*display)(const struct slice*);
unsigned int *arr;
};
struct slice *createSlice(const size_t length);
#endif
slice.c
Code:
#include <stdio.h>
#include <stdlib.h>
struct slice
{
size_t pos;
size_t length;
void (*free_slice)(const struct slice *);
void(*append)(struct slice *, unsigned int);
unsigned int (*get)(const struct slice *, size_t);
void (*display)(const struct slice*);
unsigned int *arr;
};
static void check_allocation(const void *ptr)
{
if (!ptr)
{
fputs("Allocation failed!", stderr);
exit(1);
}
}
static void display(const struct slice * s) {
size_t i = 0;
fprintf(stdout, "Pos: %ld, Length: %ld\n", s->pos, s->length);
fputs("[ ", stdout);
for (; i < s->length; i++) {
fprintf(stdout, "%d ", s->arr[i]);
}
fputs("]\n", stdout);
}
static unsigned int get(const struct slice * s, size_t pos) {
if (pos <= s->pos) {
return s->arr[pos];
}else {
exit(1);
}
}
static void append(struct slice *s, unsigned int value)
{
if (s->pos < s->length)
{
s->arr[s->pos++] = value;
return;
}
s->arr = realloc(s->arr, (s->length * 2) * sizeof(unsigned int));
check_allocation(s->arr);
s->length = s->length * 2;
s->arr[s->pos++] = value;
}
static void free_slice(const struct slice *s)
{
free((void *)s->arr);
free((void *)s);
}
struct slice *createSlice(const size_t length)
{
struct slice *s = malloc(sizeof(*s));
check_allocation(s);
s->arr = calloc(sizeof(unsigned int), length);
check_allocation(s->arr);
s->pos = 0;
s->length = length;
s->free_slice = free_slice;
s->append = append;
s->get = get;
s->display = display;
return s;
}
Am I using the static qualifier correctly here?
-
slice.h can be this if you want an opaque type.
Code:
struct slice;
struct slice *createSlice(const size_t length);
And you keep the actual struct definition in slice.c.
slice.c should include slice.h
You don't need the casts when calling free.
Be consistent in your sizeof expressions for your allocator calls.
Your get() should print a diagnostic before exiting.
> Am I using the static qualifier correctly here?
Looks good.
-
@Salem.. Thanks for the additional comments/corrections.
-
In your header file you #include <stdlib.h> outside the include-guard logic.
This means that your header file always includes another header file, even if it gets included twice.
In turn, this means that the compiler cannot "optimize away" your header file, since it always takes some action when it gets included.
Which means that repeatedly including your header file will always force the compiler to open a file, parse the contents, close the file, etc.
Better you should put the #include inside the guard logic. That will speed up compilation, as well as enabling the "skip-entire-file" logic built in to most compilers.
And you might want to consider changing to stddef.h instead of stdlib.h, since all you appear to use in the header file is size_t.