Bitwise operation with unsigned long - c

memset_pg.h
#include <stdint.h>
#include<stdio.h>
#include<string.h>
#define LONG_ALIGN_MASK (sizeof(long) - 1)
typedef size_t Size;
#define MEMSET_LOOP_LIMIT 1024
/*
* MemSet
* Exactly the same as standard library function memset(), but considerably
* faster for zeroing small word-aligned structures (such as parsetree nodes).
* This has to be a macro because the main point is to avoid function-call
* overhead. However, we have also found that the loop is faster than
* native libc memset() on some platforms, even those with assembler
* memset() functions. More research needs to be done, perhaps with
* MEMSET_LOOP_LIMIT tests in configure.
*/
#define MemSet(start, val, len) \
do \
{ \
/* must be void* because we don't know if it is integer aligned yet */ \
void *_vstart = (void *) (start); \
int _val = (val); \
Size _len = (len); \
\
printf("_vstart: %lu\n",(uintptr_t) _vstart); \
if ((((uintptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \
(_len & LONG_ALIGN_MASK) == 0 && \
_val == 0 && \
_len <= MEMSET_LOOP_LIMIT && \
/* \
* If MEMSET_LOOP_LIMIT == 0, optimizer should find \
* the whole "if" false at compile time. \
*/ \
MEMSET_LOOP_LIMIT != 0) \
{ \
long *_start = (long *) _vstart; \
long *_stop = (long *) ((char *) _start + _len); \
while (_start < _stop) \
*_start++ = 0; \
printf("non-standard MemSet invoked\n"); \
} \
else { \
memset(_vstart, _val, _len); \
printf("standard memset invoked\n"); \
} \
} while (0)
#define TEST "test"
memset_pg.c
/*
gcc -Wall -Werror memset_pg.c && ./a.out
*/
#include "memset_pg.h"
#include<stdio.h>
#include<inttypes.h>
#include<assert.h>
int main(void)
{
printf("LONG_ALIGN_MASK:%ld\n",LONG_ALIGN_MASK);
// char str[] = "beautiful earth";
char str[] = "earth567";
printf("strlen=%ld\n",strlen(str));
MemSet(str,0,strlen(str));
printf("via MemSet: str return |%s|\n",str);
printf("str pointer:%ld\n", (uintptr_t)str);
return 0;
}
I am not sure this part ((uintptr_t) _vstart) & LONG_ALIGN_MASK mean. It means at least the pointer cast to unsign long ending 3 bit should be 000. But I don't know the pattern mean.
typedef struct POD_OnlyStruct{
int a;
int b;
char d;
}POD_OnlyStruct;
POD_OnlyStruct t;
MemSet(&t,0, sizeof t);
the above will not invoke non-standard memset.
However, the following will invoke the non-standard memset.
typedef struct POD_OnlyStruct{
int a;
int b;
int c;
char d;
}POD_OnlyStruct;
POD_OnlyStruct t;
MemSet(&t,0, sizeof t);
(_len & LONG_ALIGN_MASK) == 0 means that the _len is power of 8.
In long *_stop = (long *) ((char *) _start + _len); I am not sure the usage of (char *).

I am not sure this part ((uintptr_t) _vstart) & LONG_ALIGN_MASK mean.
_vstart Is a void pointer. By casting it to a uintptr_t it becomes a number we can work with, this suppresses an error for the next operation. By doing the & LONG_ALIGN_MASK we check if this pointer is aligned to some boundry. According to the rest of your post, we check if the last three digits are zero.
The guiding text tells you why to do it. To me (purely opinion here) it needs to have a massive advantage over the memset in the libraries to be worth it, because the code is hard to read.
Edit: A new question was added:
In long *_stop = (long *) ((char *) _start + _len); I am not sure the usage of (char *)
Pointer arithmetic! A char is by definition 1 byte, but a long can be a couple more. Say we do long* a = ((long*)NULL) + 1, we now see that a = sizeof(long)/sizeof(char) = sizeof(long). This is just how pointer arithmetic works, adding one to some pointer will actually add the size of the type of the pointer to it. This is very useful when, for example, traversing an array via a pointer, plus 1 will always go to the start of the next element (given that you started at the start of some element).
So the cast to char* here makes sure that we are adding _len to _start, and not _len*sizeof(long). This usage, by the way, means that _len has to be an uintptr_t and not a size_t. A size_t is defined as the maximum array index, while uintptr_t is guaranteed to be able to contain any pointer. On most systems this does not matter (max array index == UINTPTR_MAX, usually), but technically this is an issue.
Note that casting _vstart to uintptr_t instead of (char*) would have had the same effect and maybe be more readable.

I am not sure this part ((uintptr_t) _vstart) & LONG_ALIGN_MASK mean.
This is to check whether the start address has the same alignment as a long, because if it is not, then the expression (long *) _vstart has undefined behaviour.
Note that nowadays compilers know that memset() clears memory, and will actually inline it if they see you are only setting a small amount of memory. So this MemSet() macro is completely unnecessary. In fact, some compilers might even see that the while-loop in that code is equivalent to a memset(), and replace it with a function call if they think that is more efficient (note that compilers can be told to optimize for size over performance).
In long *_stop = (long *) ((char *) _start + _len); I am not sure the usage of (char *).
This is because _start is a pointer to long. If you add _len to that, it would advance it _len times the size of long. To make sure it just adds _len bytes, you need to cast it to char * first. Also remember that ptr + offset is equivalent to &ptr[offset].

Related

Dynamic arrays with an embedded meta-information struct

I am fiddling around with an implementation of a generic dynamic array. The array should hold information about its size, how many entries are used, and then hold the actual data. The meta-information (size/used) is generic, but the data needs to handle different types, so I am handling that with macros. I am trying, however, to get the memory allocation code into functions. So my thought it is: I have a struct for meta-information
struct da_meta {
size_t size;
size_t used;
};
and then I have a macro that creates a struct per type, using a flexible array following the meta information:
#define dynarray(TYPE) \
struct { \
struct da_meta meta; \
TYPE data[]; \
}
I can declare an integer array, for example, as
dynarray(int) *int_array = 0;
To allocate and reallocate arrays, my thought was now to use code such as this:
#define size_overflow(meta_size, obj_size, len) \
((SIZE_MAX - meta_size) / obj_size < len)
// Always free if we cannot reallocate
void *realloc_dynarray_mem(void *p,
size_t meta_size,
size_t obj_size,
size_t new_len)
{
if (size_overflow(meta_size, obj_size, new_len))
goto abort;
struct da_meta *new_da =
realloc(p, meta_size + obj_size * new_len);
if (!new_da) goto abort;
new_da->size = new_len;
new_da->used = MIN(new_da->used, new_len);
return new_da;
abort:
free(p);
return 0;
}
The function gets the size of the struct sans the data objects, the size of individual objects, and the number of objects to allocate memory for. I don't use the size of the struct meta type, because it might be too small depending on the alignment of the data objects, but I will get it from sizeof the concrete (typed) structures. The function will always free the input and return NULL if I cannot allocate because in my application I have to give up if I cannot grow the array, so I don't try to preserve the old data in case there is an error.
There is nothing wrong with this code, as far as I can tell. I can always allocate memory, and as long as I have more than the size of struct meta, I can set the variables there. But when I return the result and use it as a dynarray(T) type, I am less sure. I think it should work, because C should put the memory of the first member of a struct first in a struct, and that is where I put struct meta, but am I right here?
I create a new array like this:
void *new_dynarray_mem(size_t meta_size,
size_t obj_size,
size_t len)
{
struct da_meta *array =
realloc_dynarray_mem(0, meta_size, obj_size, len);
if (array) {
// we do set size in realloc, but
array->size = len;
// if used was not initialised in realloc (and it wasn't)
// then we have to set it here...
array->used = 0;
}
return array;
}
#define new_da(type, init_size) \
new_dynarray_mem(sizeof(dynarray(type)), \
sizeof(type), init_size)
Here, the macro new_da() gets the size of the header/meta information from sizeof(dynarray(type)) and the size of the underlying types from sizeof(type). The second value is fine, but I am also uncertain about the first. Does the C standard guarantee that if I create two different structs with exactly the same code, e.g., calling dynarray(int) twice, that I get the same memory layout? I cannot imagine a compiler that would give me a different layout for the same code, but when it comes to imagining what compilers get up to, I am quite limited.
For appending to the array, I think all is fine. There I do not generate new types but get the size from the existing dynamic array, so if the first allocation is standard compliant, then I think the appending is as well, but I could be wrong.
#define da_free(da) \
do { free(da); da = 0; } while(0)
#define grow(size) \
(((size) == 0) ? /* special case for zero */ \
1 : \
((size) > SIZE_MAX / 2) ? /* can we grow? */ \
0 : /* no, then report size zero */ \
(2 * (size))) /* double the size */
#define da_append(da, ...) \
do { \
if (da->meta.used == da->meta.size) { \
size_t new_size = grow(da->meta.size); \
if (new_size == 0) { da_free(da); break; } \
da = realloc_dynarray_mem( \
da, sizeof *da, *da->data, new_size \
); \
if (!da) break; \
} \
da->data[da->meta.used++] = __VA_ARGS__; \
} while (0)
Am I guaranteed that if I lay out the concrete dynamic arrays with the meta-information at the top of the structs, then I can treat the allocate memory as both a pointer to the meta-information and the array? Is it safe to assume that I get the same size and memory layout if I generate the same struct twice? I feel that it must be that way since it shouldn't differ from if I include the same header file twice, but since I am generating the code there might be something that I am missing.
EDIT Based on the comments, I have updated the code to that below, but I have left the original code (of course) so the comments make sense in terms of that.
#define da_at(da,i) (da->data[(i)])
#define da_len(da) (da->meta.used)
struct da_meta {
size_t size;
size_t used;
};
#define dynarr(TYPE) \
struct { \
struct da_meta meta; \
TYPE data[]; \
}
// Always free if we cannot reallocate
void *realloc_dynarray_mem(struct da_meta *p,
size_t meta_size,
size_t obj_size,
size_t new_len)
{
// Size size overflow?
if (((SIZE_MAX - meta_size) / obj_size < new_len))
goto fail;
struct da_meta *new_da =
realloc(p, meta_size + obj_size * new_len);
if (!new_da) goto fail;
new_da->size = new_len;
new_da->used = MIN(new_da->used, new_len);
return new_da;
fail:
free(p);
return 0;
}
void *new_dynarray_mem(size_t meta_size,
size_t obj_size,
size_t len)
{
struct da_meta *array =
realloc_dynarray_mem(0, meta_size, obj_size, len);
if (array) array->used = 0;
return array;
}
void *grow_dynarray_mem(struct da_meta *p,
size_t meta_size,
size_t obj_size)
{
// Can we double the length?
size_t used = meta_size - obj_size * p->size;
size_t adding = MAX(1, p->size);
if ((SIZE_MAX - used) / obj_size < adding) {
free(p);
return 0;
}
return realloc_dynarray_mem(
p, meta_size, obj_size, p->size + adding
);
}
#define new_da(da, init_size) \
new_dynarray_mem(sizeof *(da), \
sizeof *(da)->data, \
(init_size))
#define da_free(da) \
do { free(da); da = 0; } while(0)
#define da_append(da, ...) \
do { \
if (da->meta.used == da->meta.size) { \
da = grow_dynarray_mem( \
(struct da_meta *)da, \
sizeof *da, sizeof *da->data \
); \
if (!da) break; \
} \
da->data[da->meta.used++] = __VA_ARGS__; \
} while (0)
When used, the code can look like this:
int main(void)
{
dynarr(int) *int_array = new_da(int_array, 0);
if (!int_array) goto error;
printf("%zu out of %zu\n",
int_array->meta.used,
int_array->meta.size);
for (int i = 0; i < 5; i++) {
da_append(int_array, i);
if (!int_array) goto error;
}
for (int i = 0; i < da_len(int_array); i++) {
printf("%d ", da_at(int_array, i));
}
printf("\n");
da_free(int_array);
return 0;
error:
return 1;
}
Just remember about padding between between meta and the start of the array and about alignment requirements and you should be fine.
because C should put the memory of the first member of a struct first in a struct, and that is where I put struct meta, but am I right here?
Yes.
Am I guaranteed that if I lay out the concrete dynamic arrays with the meta-information at the top of the structs, then I can treat the allocate memory as both a pointer to the meta-information
Yes, and...
and the array?
No. The array starts at address after meta + padding. So at address (char*)da + sizeof(dynarray(TYPE)) or just da->data.
Is it safe to assume that I get the same size and memory layout if I generate the same struct twice?
No and yes. There are many other great stackoverflow questions and answers about that topic - research them. Pragmatically yes, it would be a strange compiler that would would generate different padding for the same looking struct, but technically that's allowed.
using a flexible array
Unless you have specific aim, then I would just advise not to use them. It makes it harder for you to write the code. It makes it very hard to create and manage an array of such arrays.
goto abort;
What an unfortunate name for a goto label - abort() is a standard function.
#define grow(size)
Please use a prefix to all your library functions, especially macros. Defining such macro will make it impossible to use it in other code that happens to use a different grow() function. da_ seems like a good prefix.
I guess *da->data in realloc_dynarray_mem should be sizeof(*da->data).
#edit
I would suggest to use typeof keyword in new_da(). This would avoid specifying the type twice: in dynarray(TYPE) and in new_da(type, init_size). To make it, instead of passing the type, just pass the pointer on the dynamic array:
#define new_da(da, init_size) \
(da) = new_dynarray_mem(sizeof(dynarray(typeof(*(da)))), \
sizeof(typeof((da)->data[0])), (init_size))
Hence, this would avoid the mistake where the type used in the definition would differ from the type used in the allocation:
dynarray(int) *pInt;
pInt = new_da(char, 1024);
UPDATE FROM DISCUSSION IN COMMENTS:
And what about a single macro to define and initialize ?
#define new_da(da, type, init_size) \
dynarray(type) *da = new_dynarray_mem(sizeof(dynarray(type)), sizeof(type), init_size)

how can i show the content of my struct using a for or while? (i dont even know how to explain it, im very new at this.) [duplicate]

How do I determine the size of my array in C?
That is, the number of elements the array can hold?
Executive summary:
int a[17];
size_t n = sizeof(a)/sizeof(a[0]);
Full answer:
To determine the size of your array in bytes, you can use the sizeof
operator:
int a[17];
size_t n = sizeof(a);
On my computer, ints are 4 bytes long, so n is 68.
To determine the number of elements in the array, we can divide
the total size of the array by the size of the array element.
You could do this with the type, like this:
int a[17];
size_t n = sizeof(a) / sizeof(int);
and get the proper answer (68 / 4 = 17), but if the type of
a changed you would have a nasty bug if you forgot to change
the sizeof(int) as well.
So the preferred divisor is sizeof(a[0]) or the equivalent sizeof(*a), the size of the first element of the array.
int a[17];
size_t n = sizeof(a) / sizeof(a[0]);
Another advantage is that you can now easily parameterize
the array name in a macro and get:
#define NELEMS(x) (sizeof(x) / sizeof((x)[0]))
int a[17];
size_t n = NELEMS(a);
The sizeof way is the right way iff you are dealing with arrays not received as parameters. An array sent as a parameter to a function is treated as a pointer, so sizeof will return the pointer's size, instead of the array's.
Thus, inside functions this method does not work. Instead, always pass an additional parameter size_t size indicating the number of elements in the array.
Test:
#include <stdio.h>
#include <stdlib.h>
void printSizeOf(int intArray[]);
void printLength(int intArray[]);
int main(int argc, char* argv[])
{
int array[] = { 0, 1, 2, 3, 4, 5, 6 };
printf("sizeof of array: %d\n", (int) sizeof(array));
printSizeOf(array);
printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
printLength(array);
}
void printSizeOf(int intArray[])
{
printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}
void printLength(int intArray[])
{
printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}
Output (in a 64-bit Linux OS):
sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2
Output (in a 32-bit windows OS):
sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1
It is worth noting that sizeof doesn't help when dealing with an array value that has decayed to a pointer: even though it points to the start of an array, to the compiler it is the same as a pointer to a single element of that array. A pointer does not "remember" anything else about the array that was used to initialize it.
int a[10];
int* p = a;
assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));
The sizeof "trick" is the best way I know, with one small but (to me, this being a major pet peeve) important change in the use of parenthesis.
As the Wikipedia entry makes clear, C's sizeof is not a function; it's an operator. Thus, it does not require parenthesis around its argument, unless the argument is a type name. This is easy to remember, since it makes the argument look like a cast expression, which also uses parenthesis.
So: If you have the following:
int myArray[10];
You can find the number of elements with code like this:
size_t n = sizeof myArray / sizeof *myArray;
That, to me, reads a lot easier than the alternative with parenthesis. I also favor use of the asterisk in the right-hand part of the division, since it's more concise than indexing.
Of course, this is all compile-time too, so there's no need to worry about the division affecting the performance of the program. So use this form wherever you can.
It is always best to use sizeof on an actual object when you have one, rather than on a type, since then you don't need to worry about making an error and stating the wrong type.
For instance, say you have a function that outputs some data as a stream of bytes, for instance across a network. Let's call the function send(), and make it take as arguments a pointer to the object to send, and the number of bytes in the object. So, the prototype becomes:
void send(const void *object, size_t size);
And then you need to send an integer, so you code it up like this:
int foo = 4711;
send(&foo, sizeof (int));
Now, you've introduced a subtle way of shooting yourself in the foot, by specifying the type of foo in two places. If one changes but the other doesn't, the code breaks. Thus, always do it like this:
send(&foo, sizeof foo);
Now you're protected. Sure, you duplicate the name of the variable, but that has a high probability of breaking in a way the compiler can detect, if you change it.
int size = (&arr)[1] - arr;
Check out this link for explanation
I would advise to never use sizeof (even if it can be used) to get any of the two different sizes of an array, either in number of elements or in bytes, which are the last two cases I show here. For each of the two sizes, the macros shown below can be used to make it safer. The reason is to make obvious the intention of the code to maintainers, and difference sizeof(ptr) from sizeof(arr) at first glance (which written this way isn't obvious), so that bugs are then obvious for everyone reading the code.
TL;DR:
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + must_be_array(arr))
#define ARRAY_BYTES(arr) (sizeof(arr) + must_be_array(arr))
must_be_array(arr) (defined below) IS needed as -Wsizeof-pointer-div is buggy (as of april/2020):
#define is_same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr) (!is_same_type((arr), &(arr)[0]))
#define must_be(e) \
( \
0 * (int)sizeof( \
struct { \
static_assert(e); \
char ISO_C_forbids_a_struct_with_no_members__; \
} \
) \
)
#define must_be_array(arr) must_be(is_array(arr))
There have been important bugs regarding this topic: https://lkml.org/lkml/2015/9/3/428
I disagree with the solution that Linus provides, which is to never use array notation for parameters of functions.
I like array notation as documentation that a pointer is being used as an array. But that means that a fool-proof solution needs to be applied so that it is impossible to write buggy code.
From an array we have three sizes which we might want to know:
The size of the elements of the array
The number of elements in the array
The size in bytes that the array uses in memory
The size of the elements of the array
The first one is very simple, and it doesn't matter if we are dealing with an array or a pointer, because it's done the same way.
Example of usage:
void foo(size_t nmemb, int arr[nmemb])
{
qsort(arr, nmemb, sizeof(arr[0]), cmp);
}
qsort() needs this value as its third argument.
For the other two sizes, which are the topic of the question, we want to make sure that we're dealing with an array, and break the compilation if not, because if we're dealing with a pointer, we will get wrong values. When the compilation is broken, we will be able to easily see that we weren't dealing with an array, but with a pointer instead, and we will just have to write the code with a variable or a macro that stores the size of the array behind the pointer.
The number of elements in the array
This one is the most common, and many answers have provided you with the typical macro ARRAY_SIZE:
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
Recent versions of compilers, such as GCC 8, will warn you when you apply this macro to a pointer, so it is safe (there are other methods to make it safe with older compilers).
It works by dividing the size in bytes of the whole array by the size of each element.
Examples of usage:
void foo(size_t nmemb)
{
char buf[nmemb];
fgets(buf, ARRAY_SIZE(buf), stdin);
}
void bar(size_t nmemb)
{
int arr[nmemb];
for (size_t i = 0; i < ARRAY_SIZE(arr); i++)
arr[i] = i;
}
If these functions didn't use arrays, but got them as parameters instead, the former code would not compile, so it would be impossible to have a bug (given that a recent compiler version is used, or that some other trick is used), and we need to replace the macro call by the value:
void foo(size_t nmemb, char buf[nmemb])
{
fgets(buf, nmemb, stdin);
}
void bar(size_t nmemb, int arr[nmemb])
{
for (size_t i = nmemb - 1; i < nmemb; i--)
arr[i] = i;
}
The size in bytes that the array uses in memory
ARRAY_SIZE is commonly used as a solution to the previous case, but this case is rarely written safely, maybe because it's less common.
The common way to get this value is to use sizeof(arr). The problem: the same as with the previous one; if you have a pointer instead of an array, your program will go nuts.
The solution to the problem involves using the same macro as before, which we know to be safe (it breaks compilation if it is applied to a pointer):
#define ARRAY_BYTES(arr) (sizeof((arr)[0]) * ARRAY_SIZE(arr))
How it works is very simple: it undoes the division that ARRAY_SIZE does, so after mathematical cancellations you end up with just one sizeof(arr), but with the added safety of the ARRAY_SIZE construction.
Example of usage:
void foo(size_t nmemb)
{
int arr[nmemb];
memset(arr, 0, ARRAY_BYTES(arr));
}
memset() needs this value as its third argument.
As before, if the array is received as a parameter (a pointer), it won't compile, and we will have to replace the macro call by the value:
void foo(size_t nmemb, int arr[nmemb])
{
memset(arr, 0, sizeof(arr[0]) * nmemb);
}
Update (23/apr/2020): -Wsizeof-pointer-div is buggy:
Today I found out that the new warning in GCC only works if the macro is defined in a header that is not a system header. If you define the macro in a header that is installed in your system (usually /usr/local/include/ or /usr/include/) (#include <foo.h>), the compiler will NOT emit a warning (I tried GCC 9.3.0).
So we have #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) and want to make it safe. We will need C2X static_assert() and some GCC extensions: Statements and Declarations in Expressions, __builtin_types_compatible_p:
#include <assert.h>
#define is_same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr) (!is_same_type((arr), &(arr)[0]))
#define Static_assert_array(arr) static_assert(is_array(arr))
#define ARRAY_SIZE(arr) \
({ \
Static_assert_array(arr); \
sizeof(arr) / sizeof((arr)[0]); \
})
Now ARRAY_SIZE() is completely safe, and therefore all its derivatives will be safe.
Update: libbsd provides __arraycount():
Libbsd provides the macro __arraycount() in <sys/cdefs.h>, which is unsafe because it lacks a pair of parentheses, but we can add those parentheses ourselves, and therefore we don't even need to write the division in our header (why would we duplicate code that already exists?). That macro is defined in a system header, so if we use it we are forced to use the macros above.
#inlcude <assert.h>
#include <stddef.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#define is_same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr) (!is_same_type((arr), &(arr)[0]))
#define Static_assert_array(arr) static_assert(is_array(arr))
#define ARRAY_SIZE(arr) \
({ \
Static_assert_array(arr); \
__arraycount((arr)); \
})
#define ARRAY_BYTES(arr) (sizeof((arr)[0]) * ARRAY_SIZE(arr))
Some systems provide nitems() in <sys/param.h> instead, and some systems provide both. You should check your system, and use the one you have, and maybe use some preprocessor conditionals for portability and support both.
Update: Allow the macro to be used at file scope:
Unfortunately, the ({}) gcc extension cannot be used at file scope.
To be able to use the macro at file scope, the static assertion must be
inside sizeof(struct {}). Then, multiply it by 0 to not affect
the result. A cast to (int) might be good to simulate a function
that returns (int)0 (in this case it is not necessary, but then it
is reusable for other things).
Additionally, the definition of ARRAY_BYTES() can be simplified a bit.
#include <assert.h>
#include <stddef.h>
#include <sys/cdefs.h>
#include <sys/types.h>
#define is_same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#define is_array(arr) (!is_same_type((arr), &(arr)[0]))
#define must_be(e) \
( \
0 * (int)sizeof( \
struct { \
static_assert(e); \
char ISO_C_forbids_a_struct_with_no_members__; \
} \
) \
)
#define must_be_array(arr) must_be(is_array(arr))
#define ARRAY_SIZE(arr) (__arraycount((arr)) + must_be_array(arr))
#define ARRAY_BYTES(arr) (sizeof(arr) + must_be_array(arr))
Notes:
This code makes use of the following extensions, which are completely necessary, and their presence is absolutely necessary to achieve safety. If your compiler doesn't have them, or some similar ones, then you can't achieve this level of safety.
__builtin_types_compatible_p()
typeof()
I also make use of the following C2X feature. However, its absence by using an older standard can be overcome using some dirty tricks (see for example: What is “:-!!” in C code?) (in C11 you also have static_assert(), but it requires a message).
static_assert()
You can use the sizeof operator, but it will not work for functions, because it will take the reference of a pointer.
You can do the following to find the length of an array:
len = sizeof(arr)/sizeof(arr[0])
The code was originally found here:
C program to find the number of elements in an array
If you know the data type of the array, you can use something like:
int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22};
int noofele = sizeof(arr)/sizeof(int);
Or if you don't know the data type of array, you can use something like:
noofele = sizeof(arr)/sizeof(arr[0]);
Note: This thing only works if the array is not defined at run time (like malloc) and the array is not passed in a function. In both cases, arr (array name) is a pointer.
The macro ARRAYELEMENTCOUNT(x) that everyone is making use of evaluates incorrectly. This, realistically, is just a sensitive matter, because you can't have expressions that result in an 'array' type.
/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x[0]))
ARRAYELEMENTCOUNT(p + 1);
Actually evaluates as:
(sizeof (p + 1) / sizeof (p + 1[0]));
Whereas
/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0])
ARRAYELEMENTCOUNT(p + 1);
It correctly evaluates to:
(sizeof (p + 1) / sizeof (p + 1)[0]);
This really doesn't have a lot to do with the size of arrays explicitly. I've just noticed a lot of errors from not truly observing how the C preprocessor works. You always wrap the macro parameter, not an expression in might be involved in.
This is correct; my example was a bad one. But that's actually exactly what should happen. As I previously mentioned p + 1 will end up as a pointer type and invalidate the entire macro (just like if you attempted to use the macro in a function with a pointer parameter).
At the end of the day, in this particular instance, the fault doesn't really matter (so I'm just wasting everyone's time; huzzah!), because you don't have expressions with a type of 'array'. But really the point about preprocessor evaluation subtles I think is an important one.
For multidimensional arrays it is a tad more complicated. Oftenly people define explicit macro constants, i.e.
#define g_rgDialogRows 2
#define g_rgDialogCols 7
static char const* g_rgDialog[g_rgDialogRows][g_rgDialogCols] =
{
{ " ", " ", " ", " 494", " 210", " Generic Sample Dialog", " " },
{ " 1", " 330", " 174", " 88", " ", " OK", " " },
};
But these constants can be evaluated at compile-time too with sizeof:
#define rows_of_array(name) \
(sizeof(name ) / sizeof(name[0][0]) / columns_of_array(name))
#define columns_of_array(name) \
(sizeof(name[0]) / sizeof(name[0][0]))
static char* g_rgDialog[][7] = { /* ... */ };
assert( rows_of_array(g_rgDialog) == 2);
assert(columns_of_array(g_rgDialog) == 7);
Note that this code works in C and C++. For arrays with more than two dimensions use
sizeof(name[0][0][0])
sizeof(name[0][0][0][0])
etc., ad infinitum.
Size of an array in C:
int a[10];
size_t size_of_array = sizeof(a); // Size of array a
int n = sizeof (a) / sizeof (a[0]); // Number of elements in array a
size_t size_of_element = sizeof(a[0]); // Size of each element in array a
// Size of each element = size of type
sizeof(array) / sizeof(array[0])
#define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0]))
If you really want to do this to pass around your array I suggest implementing a structure to store a pointer to the type you want an array of and an integer representing the size of the array. Then you can pass that around to your functions. Just assign the array variable value (pointer to first element) to that pointer. Then you can go Array.arr[i] to get the i-th element and use Array.size to get the number of elements in the array.
I included some code for you. It's not very useful but you could extend it with more features. To be honest though, if these are the things you want you should stop using C and use another language with these features built in.
/* Absolutely no one should use this...
By the time you're done implementing it you'll wish you just passed around
an array and size to your functions */
/* This is a static implementation. You can get a dynamic implementation and
cut out the array in main by using the stdlib memory allocation methods,
but it will work much slower since it will store your array on the heap */
#include <stdio.h>
#include <string.h>
/*
#include "MyTypeArray.h"
*/
/* MyTypeArray.h
#ifndef MYTYPE_ARRAY
#define MYTYPE_ARRAY
*/
typedef struct MyType
{
int age;
char name[20];
} MyType;
typedef struct MyTypeArray
{
int size;
MyType *arr;
} MyTypeArray;
MyType new_MyType(int age, char *name);
MyTypeArray newMyTypeArray(int size, MyType *first);
/*
#endif
End MyTypeArray.h */
/* MyTypeArray.c */
MyType new_MyType(int age, char *name)
{
MyType d;
d.age = age;
strcpy(d.name, name);
return d;
}
MyTypeArray new_MyTypeArray(int size, MyType *first)
{
MyTypeArray d;
d.size = size;
d.arr = first;
return d;
}
/* End MyTypeArray.c */
void print_MyType_names(MyTypeArray d)
{
int i;
for (i = 0; i < d.size; i++)
{
printf("Name: %s, Age: %d\n", d.arr[i].name, d.arr[i].age);
}
}
int main()
{
/* First create an array on the stack to store our elements in.
Note we could create an empty array with a size instead and
set the elements later. */
MyType arr[] = {new_MyType(10, "Sam"), new_MyType(3, "Baxter")};
/* Now create a "MyTypeArray" which will use the array we just
created internally. Really it will just store the value of the pointer
"arr". Here we are manually setting the size. You can use the sizeof
trick here instead if you're sure it will work with your compiler. */
MyTypeArray array = new_MyTypeArray(2, arr);
/* MyTypeArray array = new_MyTypeArray(sizeof(arr)/sizeof(arr[0]), arr); */
print_MyType_names(array);
return 0;
}
The best way is you save this information, for example, in a structure:
typedef struct {
int *array;
int elements;
} list_s;
Implement all necessary functions such as create, destroy, check equality, and everything else you need. It is easier to pass as a parameter.
The function sizeof returns the number of bytes which is used by your array in the memory. If you want to calculate the number of elements in your array, you should divide that number with the sizeof variable type of the array. Let's say int array[10];, if variable type integer in your computer is 32 bit (or 4 bytes), in order to get the size of your array, you should do the following:
int array[10];
size_t sizeOfArray = sizeof(array)/sizeof(int);
A more elegant solution will be
size_t size = sizeof(a) / sizeof(*a);
You can use the & operator. Here is the source code:
#include<stdio.h>
#include<stdlib.h>
int main(){
int a[10];
int *p;
printf("%p\n", (void *)a);
printf("%p\n", (void *)(&a+1));
printf("---- diff----\n");
printf("%zu\n", sizeof(a[0]));
printf("The size of array a is %zu\n", ((char *)(&a+1)-(char *)a)/(sizeof(a[0])));
return 0;
};
Here is the sample output
1549216672
1549216712
---- diff----
4
The size of array a is 10
The simplest answer:
#include <stdio.h>
int main(void) {
int a[] = {2,3,4,5,4,5,6,78,9,91,435,4,5,76,7,34}; // For example only
int size;
size = sizeof(a)/sizeof(a[0]); // Method
printf("size = %d", size);
return 0;
}
"you've introduced a subtle way of shooting yourself in the foot"
C 'native' arrays do not store their size. It is therefore recommended to save the length of the array in a separate variable/const, and pass it whenever you pass the array, that is:
#define MY_ARRAY_LENGTH 15
int myArray[MY_ARRAY_LENGTH];
If you are writing C++, you SHOULD always avoid native arrays anyway (unless you can't, in which case, mind your foot). If you are writing C++, use the STL's 'vector' container. "Compared to arrays, they provide almost the same performance", and they are far more useful!
// vector is a template, the <int> means it is a vector of ints
vector<int> numbers;
// push_back() puts a new value at the end (or back) of the vector
for (int i = 0; i < 10; i++)
numbers.push_back(i);
// Determine the size of the array
cout << numbers.size();
See:
http://www.cplusplus.com/reference/stl/vector/
Beside the answers already provided, I want to point out a special case by the use of
sizeof(a) / sizeof (a[0])
If a is either an array of char, unsigned char or signed char you do not need to use sizeof twice since a sizeof expression with one operand of these types do always result to 1.
Quote from C18,6.5.3.4/4:
"When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1."
Thus, sizeof(a) / sizeof (a[0]) would be equivalent to NUMBER OF ARRAY ELEMENTS / 1 if a is an array of type char, unsigned char or signed char. The division through 1 is redundant.
In this case, you can simply abbreviate and do:
sizeof(a)
For example:
char a[10];
size_t length = sizeof(a);
If you want a proof, here is a link to GodBolt.
Nonetheless, the division maintains safety, if the type significantly changes (although these cases are rare).
To know the size of a fixed array declared explicitly in code and referenced by its variable, you can use sizeof, for example:
int a[10];
int len = sizeof(a)/sizeof(int);
But this is usually useless, because you already know the answer.
But if you have a pointer you can’t use sizeof, its a matter of principle.
But...Since arrays are presented as linear memory for the user, you can calculate the size if you know the last element address and if you know the size of the type, then you can count how many elements it have. For example:
#include <stdio.h>
int main(){
int a[10];
printf("%d\n", sizeof(a)/sizeof(int));
int *first = a;
int *last = &(a[9]);
printf("%d\n", (last-first) + 1);
}
Output:
10
10
Also if you can't take advantage of compile time you can:
#include <stdio.h>
int main(){
int a[10];
printf("%d\n", sizeof(a)/sizeof(int));
void *first = a;
void *last = &(a[9]);
printf("%d\n", (last-first)/sizeof(int) + 1);
}
Note: This one can give you undefined behaviour as pointed out by M.M in the comment.
int a[10];
int size = (*(&a+1)-a);
For more details, see here and also here.
For a predefined array:
int a[] = {1, 2, 3, 4, 5, 6};
Calculating number of elements in the array:
element _count = sizeof(a) / sizeof(a[0]);

Explain line of C code in qsort

I've been looking at different implementations of qsort, and there's a line in the source found here (https://code.woboq.org/userspace/glibc/stdlib/qsort.c.html) that I don't understand. It looks like a function pointer declaration. I'd appreciate any help. I've included as much code as necessary (with the line noted) to I think answer the question. Please let me know if not, thanks.
typedef struct
{
char *lo;
char *hi;
} stack_node;
void _quicksort (void *const pbase, size_t total_elems, size_t size, cmp_t cmp, void *arg)
{
char *base_ptr = (char *) pbase;
const size_t max_thresh = 4 * size;
if (total_elems == 0)
return;
if (total_elems > 4)
{
char *lo = base_ptr;
char *hi = &lo[size * (total_elems - 1)];
stack_node stack[(8 * sizeof(size_t))];
stack_node *top = stack;
/* Line below is a function pointer declaration? Initializes struct? */
((void) ((top->lo = (((void*)0))), (top->hi = (((void*)0))), ++top));
while ((stack < top))
{
char *left_ptr;
char *right_ptr;
char *mid = lo + size * ((hi - lo) / size >> 1);
... code goes on
No, it is not a function pointer declaration. It is just a convoluted way to say
top->lo = 0;
top->hi = 0;
++top;
You can rewrite the above as a single expression statement using , operator
top->lo = 0, top->hi = 0, ++top;
then add unnecessary casts
top->lo = (void *) 0, top->hi = (void *) 0, ++top;
and a bunch of redundant ()s
(top->lo = (((void *) 0))), (top->hi = (((void *) 0))), ++top;
and then cast the whole thing to (void) (say, to suppress any potential compiler warnings about expression result's being "unused")
((void) ((top->lo = (((void *) 0))), (top->hi = (((void *) 0))), ++top));
and now you have your original version.
Why someone decided to use that strange syntax with , operator and massive amount of redundant () is not clear to me. Looks like a macro expansion. Maybe it is a piece of already-preprocessed code? The ((void *) 0) parts might easily be preprocessor replacements for standard NULL macro.
Looking at the URL we discover that the line is actually a macro definition in particular
/* The next 4 #defines implement a very fast in-line stack abstraction. */
/* The stack needs log (total_elements) entries (we could even subtract
log(MAX_THRESH)). Since total_elements has type size_t, we get as
upper bound for log (total_elements):
bits per byte (CHAR_BIT) * sizeof(size_t). */
#define STACK_SIZE (CHAR_BIT * sizeof(size_t))
#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
#define STACK_NOT_EMPTY (stack < top)
and the code actually appears in the definition of PUSH and its compendium appears in POP. The use of extra ()s is to ensure that ++top and --top happen inline and in the correct sequence.
The reason it's implemented this way is clearer when we see the Copyright (C) 1991 - 2017 message at the top of the qsort.c ... Compilers in 1991 were probably really sucky at inlining functions.

Passing a type as a parameter

ETA: This is NOT about malloc(), or memory allocation, it's about passing a type as a parameter, like:
va_arg(l, char);
I'm using malloc() as a simple example.
This might be a stupid question, or perhaps I'm missing something.
Let's imagine I want to write a simple function that allocates some memory, not any particular type of memory but something more flexible.
Like, say I wanted 1,000 chars allocated and returned. So I'd like a function that I can call like this:
ptr = getMem(char, 1000);
Pasing the actual type as a parameter, which could be useful.
Now I know macros like va_arg() can do this:
fprintf(stdout, "%s\n", va_arg(l, char));
So I looked into it a bit, it's all rather vague. I found this:
type va_arg(va_list ap, type)
Parameters
ap − This is the object of type va_list with information about the additional arguments and their retrieval state. This object should be initialized by an initial call to va_start before the first call to va_arg.
type − This is a type name. This type name is used as the type of the expression, this macro expands to.
You can see cleary the type for the first parameter is defined as va_list,
but the second parameter, the one I'm interested in - is simply specified as type.
So it started to bug me, I've been messing around with bum code like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void *getMem(type, int size) {
return malloc(sizeof(type) * size);
}
int main(void)
{
void *mem;
mem = getMem(1000, char);
if (mem == NULL) {
perror("malloc()");
exit(EXIT_FAILURE);
}
fprintf(stdout, "Memory allocated successfully!\n");
free(mem);
exit(EXIT_SUCCESS);
}
I've been sniffing around include files trying to figure this out but to no avail, is there a way I can do this?
Sorry if it's a bit vague or nonsensical, but if va_arg() can do it I reckon I should be able to, also.
Much obliged.
Do this with a CPP macro:
#define getMem(type, size) \
malloc(sizeof(type) * size)
However, personally, I prefer this:
#define getMemOf(ptr, size) \
ptr = malloc(sizeof(*ptr) * size)
// invoke with:
getMemOf(ptr, 1000);
_Generic in C99 C11 may offer something close to OP's need.
Example: Code wants to assign the maximum value of a common integer type.
#define integer_max(X) _Generic((X), \
unsigned long long: ULLONG_MAX, \
long long: LLONG_MAX, \
unsigned long: ULONG_MAX, \
long: LONG_MAX, \
unsigned: UINT_MAX, \
int: INT_MAX, \
unsigned short: USHRT_MAX, \
short: SHRT_MAX, \
unsigned char: UCHAR_MAX, \
signed char: SCHAR_MAX, \
char: CHAR_MAX, \
_Bool: 1, \
default: 1/0 \
)
// Here the _type_ of `x` is used by integer_max(), not its value.
some_integer_type x = integer_max(x);
You are going to end up doing this with sizeof anyway. I just checked this in Visual Studio, and Microsoft defines it as (across several defines)
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define _crt_va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_arg _crt_va_arg
You can find these in vadefs.h. Long story short, you're not going to get away from using sizeof somewhere, so you should just do it where it is most simple. Personally I think that'd be just passing the size into your getMem function instead of the type will save you way more headache in the long run.
malloc() does not need to know the type to work well, just the size of the type.
Should code want to insure no overflow in the size calculation, a check could be made.
void *getMem(size_t element_count, size_t type_size) {
if (element_count > SIZE_MAX/type_size) return NULL;
return malloc(element_count * size);
}
// usage example
size_t element_count,
void * p = getMem(element_count, sizeof (char));
If one wants zero-ed memory, simple use calloc()
// usage example
size_t element_count,
void * p = calloc(element_count, sizeof (char));
Recommend that code not use void * pointers and expresses a type like char separately. Instead, declare a pointer with a non-void type.
#define ALLOCATE_ASSIGN(addr_ptr, count) (*(addr_ptr)=malloc(sizeof **(addr_ptr) * count))
some_type *mem;
ALLOCATE_ASSIGN(&mem, element_count);

Is it possible to create generic functions in C?

I am getting back into using C, but I've been spoiled by generics in other languages. I have made it to the following piece of code in my implementation of a resizable array:
typdef struct {
void** array;
int length;
int capacity;
size_t type_size;
} Vector;
void vector_add(Vector* v, void* entry) {
// ... code for adding to the array and resizing
}
int main() {
Vector* vector = vector_create(5, sizeof(int));
vector_add(vector, 4); // This is erroneous...
// ...
}
In my attempt to make this generic, I'm now unable to add an integer to the vector without storing it in memory somewhere else.
Is there any way to make this work (either as is, or possibly a better approach to generics)?
For my answer I am assuming that you are not familiar with the sections of memory (ie the use of the memory pool).
In my attempt to make this generic, I'm now unable to add an integer to the vector without storing it in memory somewhere else.
If you want to create a generic structure (as you did) then you will need to use void pointers. Consequently, from the use of void pointers you will need to store the values for each field on the memory pool, or uncommonly on the stack. Note, the structure is composed of void pointers and hence only memory addresses are contained within the structure, pointing to other locations in memory where the values are.
Be careful if you declare them on the stack as once your stack frame is popped from the call stack those memory addresses are not considered to be valid and hence may be used by another stack frame (overwriting your existing values within that collection of memory addresses).
Aside: If you migrate to C++ then you can consider the use of C++ templates.
Yes; you can embrace Greenspun's Tenth Rule and develop a full blown dynamic language in C, and in the process, develop a relatively clean C run time that can be used from within C.
In this project I did just that, as have others before me.
In the C run time of this project, a generic number would be created from a C number like this:
val n = num(42);
because of the way val is represented, it takes up only a machine word. A few bits of type tag are used to distinguish a number from a pointer, from a character, etc.
There is also this:
val n = num_fast(42);
which is much faster (a bit manipulation macro) because it doesn't do any special checks that the number 42 fits into the "fixnum" range; it's used for small integers.
A function that adds its argument to every element of a vector could be written (very inefficiently) like this:
val vector_add(val vec, val delta)
{
val iter;
for (iter = zero; lt(iter, length(vec)); iter = plus(iter, one)) {
val *pelem = vecref_l(vec, iter);
*pelem = plus(*pelem, delta);
}
return nil;
}
Since plus is generic, this will work with fixnums, bignums and reals, as well as with characters, since it is possible to add integer displacements to characters via plus.
Type mismatch errors will be caught by the lower level functions and turned into exceptions. For instance if vec isn't something to which length can be applied, length will throw.
Functions with a _l suffix return a location. Wherease vecref(v, i) returns the value at offset i in vector v, vecref_l(v, i) returns a pointer to the val typed location in the vector which stores that value.
It's all C, just with the ISO C rules bent a little bit: you can't make a type like val efficiently in strictly conforming C, but you can do it quite portably to architectures and compilers you care about supporting.
Our vector_add isn't generic enough. It's possible to do better:
val sequence_add(val vec, val delta)
{
val iter;
for (iter = zero; lt(iter, length(vec)); iter = plus(iter, one)) {
val elem = ref(vec, iter);
refset(vec, iter, plus(elem, delta));
}
return nil;
}
By using the generic ref and refset, this now works with lists and strings also, not only vectors. We can do something like:
val str = string(L"abcd");
sequence_add(str, num(2));
The contents of str will change to cdef since a displacement of 2 is added to each character, in place.
Your idea can be done:
int *new_int = (int*)malloc(sizeof(int));
*new_int = 4;
vector_add(vector, new_int);
Naturally, it would be a good idea to do a int *create_int(int x) function or something similar:
int *create_int(int x)
{
int *n = (int*)malloc(sizeof(int));
*n = 4;
return n;
}
//...
vector_add(vector, create_int(4));
If your environment allows it you may consider using a well tested, widely used library that already manages all that, such as Glib. Or even C++.
You can avoid having many many small allocations by storing the data instead of pointers to it, like
typedef struct {
char* array;
int length;
int capacity;
size_t type_size;
} Vector;
bool vector_add(Vector* v, void* entry)
{
if (v->length < v->capacity || vector_expand(v)) {
char* location = v->array + (v->length++)*(v->type_size);
memcpy(location, entry, v->type_size);
return 1;
}
return 0; // didn't fit
}
int main()
{
Vector* vector = vector_create(5, sizeof(int));
int value = 4;
vector_add(vector, &value); // pointer to local is ok because the pointer isn't stored, only used for memcpy
}
Yes, here's an implementation of mine (similar to yours) that may help. It uses macros that can be wrapped with function calls for immediate values.
#ifndef VECTOR_H
# define VECTOR_H
# include <stddef.h>
# include <string.h>
# define VECTOR_HEADROOM 4
/* A simple library for dynamic
* string/array manipulation
*
* Written by: Taylor Holberton
* During: July 2013
*/
struct vector {
void * data;
size_t size, len;
size_t headroom;
};
int vector_init (struct vector *);
size_t vector_addc (struct vector *, int index, char c);
size_t vector_subc (struct vector *, int index);
// these ones are just for strings (I haven't yet generalized them)
size_t vector_adds (struct vector *, int index, int iend, const char * c);
size_t vector_subs (struct vector *, int ibegin, int iend);
size_t vector_addi (struct vector *, int index, int i);
size_t vector_subi (struct vector *, int index);
# define vector_addm(v, index, datatype, element) \
do { \
if (!v) return 0; \
\
if (!v->size){ \
v->data = calloc (v->headroom, sizeof (datatype)); \
v->size = v->headroom; \
} \
\
datatype * p = v->data; \
\
if (v->len >= (v->size - 2)){ \
v->data = realloc (v->data, \
(v->size + v->headroom) * sizeof (datatype)); \
p = v->data; \
memset (&p[v->size], 0, v->headroom * sizeof(datatype));\
v->size += v->headroom; \
} \
\
if ((index < 0) || (index > v->len)){ \
index = v->len; \
} \
\
for (int i = v->len; i >= index; i--){ \
p[i + 1] = p[i]; \
} \
\
p[index] = element; \
\
v->len++; \
\
} while (0)
# define vector_subm(v, index, datatype) \
do { \
if (!v || !v->len){ \
return 0; \
} \
\
if ((index < 0) || (index > (v->len - 1))){ \
index = v->len - 1; \
} \
\
datatype * p = v->data; \
\
for (int i = index; i < v->len; i++){ \
p[i] = p[i + 1]; \
} \
\
v->len--; \
\
if ((v->size - v->len) > v->headroom){ \
v->data = realloc (v->data, ((v->size - v->headroom) + 1) * sizeof (datatype));\
v->size -= v->headroom; \
} \
\
} while (0)
#endif
And I usually wrap them like:
size_t vector_addi (struct vector * v, int index, int i){
vector_addm (v, index, int, i);
return v->len;
}
I haven't had this code-reviewed, but I've been using it in a large program I'm writing and I haven't had any memory errors from them (using valgrind).
The only thing that is really missing (I've been meaning to add) the ability to add and subtract arrays from arrays.
Edit: I believe you can also do this same sort of thing with stdarg.h, but I've never tried it.
You asked for a better approach? Here ist is: https://github.com/m-e-leypold/glitzersachen-demos/tree/master/generix/v0-2011 (Disclosure: This is my code).
Let me explain very shortly:
I wanted type safe generic containers (which in other languages would be provided by proper generics (Ada) or parametric polymorphism (OCaml). This is the the feature that is most missing in C.
Macros just cannot do it (I'm not
going to explain that in detail. Suffice to say: The result of a template expansion or
generic instantiation should be a module in it's own right: In C this means, there are pre
processor symbols exported respectively can be used for module configuration (like
-DUSE_PROCESS_QUEUE_DEBUGCODE) you couldn't do that if you used C macros to generate
instances.
I'm abstracting over element type by moving element size and all relevant operation into a descriptive structure. This will be passed to every invocation of the generic code. Note that the descriptor describes the element type, so a descriptor instance will be needed once per generic instance.
I'm using a template processor to create a thin type safe frontend module to the generic code.
Example:
This is the prototype for the generic code to retrieve an element:
void fifo_get ( fifo_DESCRIPTOR* inst, fifo* , void* var );
This is the descriptor type:
typedef struct fifo_DESCRIPTOR {
size_t maxindex;
size_t element_size;
} fifo_DESCRIPTOR;
This is the template code in the type safe wrapper template:
<<eT>> <<>>get ( <<T>>* f ) {
<<eT>> e; fifo_get( &DESCRIPTOR, (fifo*) f, (void*) &e ); return e;
}
And this is what the template expander (instantiating an generic) produces from the template:
float floatq_get ( floatq* f ) {
float e; fifo_get( &DESCRIPTOR, (fifo*) f, (void*) &e ); return e;
}
All this has a nice make integration, but hardly any type safety in instantiation. Every error only crops up when compiling with cc.
I cannot justify at the moment, why to stick with source text templates in C instead of migrating to C++. For me, it was just an experiment.
Regards.
This approach will probably horrify you, but it can be made to work if you don't need any type-specialized logic:
// vector.h
#ifndef VECTOR_H
#define VECTOR_H
#define VECTOR_IMP(itemType) \
typedef struct { \
itemType * array; \
int length; \
int capacity; \
} itemType##_Vector; \
\
static inline void itemType##_vector_add(itemType##_Vector* v, itemType v) { \
// implementation of adding an itemType object to the array goes here \
} \
\
[... other static-inline generic vector methods would go here ...] \
// Now we can "instantiate" versions of the Vector struct and methods for
// whatever types we want to use.
VECTOR_IMP(int);
VECTOR_IMP(float);
VECTOR_IMP(char);
#endif
... and some example calling code:
#include "vector.h"
int main(int argc, char ** argv)
{
float_Vector fv = {0};
int_Vector iv = {0};
char_Vector cv = {0};
int_vector_add(&iv, 5);
float_vector_add(&fv, 3.14f);
char_vector_add(&cv, 'A');
return 0;
}
Instead of having the vector class store the added object, you could just return a pointer to the location where the caller can store it:
typdef struct {
char *buffer;
size_t length;
size_t capacity;
size_t type_size;
} Vector;
void *vector_add(Vector* v)
{
if (v->length == v->capacity) {
// ... increase capacity by at least one
// ... realloc buffer to capacity * type_size
}
return v->buffer + v->type_size * v->length++;
}
// in main:
*(int*)vector_add(v) = 4;
Using some non-standard GNU C extensions, it is possible to define generic functions with inferred parameter types. This macro defines a nested function in a statement expression and infers the parameter type using typeof:
#include <stdio.h>
#define fib(n1) ({\
typeof(n1) func(typeof(n1) n){\
if (n <= 1)\
return n;\
return func(n-1) + func(n-2);\
}\
func(n1);\
})
int main()
{
printf("%d\n",fib(3));
printf("%f\n",fib(3.0));
return 0;
}

Resources