Once-only pseudo-generic header in C - c

After some work on the generic vector I asked about on this question, I would like to know if there is any way of checking that each instanciation of the library is only done once per type.
Here is what the current header file looks like:
#ifndef VECTOR_GENERIC_MACROS
#define VECTOR_GENERIC_MACROS
#ifndef TOKENPASTE
#define TOKENPASTE(a, b) a ## b
#endif
#define vector_t(T) TOKENPASTE(vector_t_, T)
#define vector_at(T) TOKENPASTE(*vector_at_, T)
#define vector_init(T) TOKENPASTE(vector_init_, T)
#define vector_destroy(T) TOKENPASTE(vector_destroy_, T)
#define vector_new(T) TOKENPASTE(vector_new_, T)
#define vector_delete(T) TOKENPASTE(vector_delete_, T)
#define vector_push_back(T) TOKENPASTE(vector_push_back_, T)
#define vector_pop_back(T) TOKENPASTE(vector_pop_back_, T)
#define vector_resize(T) TOKENPASTE(vector_resize_, T)
#define vector_reserve(T) TOKENPASTE(vector_reserve_, T)
#endif
typedef struct {
size_t size;
size_t capacity;
TYPE *data;
} vector_t(TYPE);
inline TYPE vector_at(TYPE)(vector_t(TYPE) *vector, size_t pos);
void vector_init(TYPE)(vector_t(TYPE) *vector, size_t size);
void vector_destroy(TYPE)(vector_t(TYPE) *vector);
inline TYPE *vector_new(TYPE)(size_t size);
inline void vector_delete(TYPE)(vector_t(TYPE) *vector);
void vector_push_back(TYPE)(vector_t(TYPE) *vector, TYPE value);
inline TYPE vector_pop_back(TYPE)(vector_t(TYPE) *vector);
inline void vector_resize(TYPE)(vector_t(TYPE) *vector, size_t size);
void vector_reserve(TYPE)(vector_t(TYPE) *vector, size_t size);
The header can then be included along with the source definitions:
#include <stdio.h>
#define TYPE int
#include "vector.h"
#include "vector.def"
#undef TYPE
int main()
{
vector_t(int) myVectorInt;
vector_init(int)(&myVectorInt, 0);
for (int i = 0; i < 10; ++i)
vector_push_back(int)(&myVectorInt, i);
for (int i = 0; i < myVectorInt.size; ++i)
printf("%d ", ++vector_at(int)(&myVectorInt, i));
vector_destroy(int)(&myVectorInt);
return 0;
}
I would like to make sure that the content below that last endif is only included once per TYPE.
Obviously, #ifdef VECTOR_INSTANCE(TYPE) does not work, so I'm really out of ideas...

It's a though question, however, I was also interested in the matter when I asked a similar question to yours some time ago.
My conclusions is that if you are going to use vectors (or, using more accurate naming, dynamic arrays) of many different types then it's wasteful to have all those functions vector_##TYPE##_reserve(), vector_##type##_resize(), etc... multiple times.
Instead, it is more efficient and clean to have those functions defined only once in a separate .c file, using your type's size as an extra argument. Those functions prototyped in a separate .h file. Then the same .h file would provide macros that generate functions wrappers for your own types, so that you don't see it using the size as an extra argument.
For example, your vector.h header would contain the following :
/* Declare functions operating on a generic vector type */
void vector_generic_resize(void *vector, size_t size, size_t data_size);
void vector_generic_push_back(void *vector, void *value, size_t data_size);
void *vector_generic_pop_back(void *vector, size_t data_size);
void vector_generic_init(void *vector, size_t size, size_t data_size);
void vector_generic_destroy(void *vector) ; // I don't think data_size is needed here
/* Taken from the example in the question */
#define VECTOR_DEFINITION(type)\
typedef struct {\
size_t size;\
size_t capacity;\
type *data;\
} vector_ ## type ## _t;\
/* Declare wrapper macros to make the above functions usable */
/* First the easy ones */
#define vector_resize(vector, size) vector_generic_resize(vector, size, sizeof(vector.data[0]))
#define vector_init(vector, size) vector_generic_init(vector, size, sizeof(vector.data[0]))
/* Type has to be given as an argument for the cast operator */
#define vector_pop_back(vector, type) (*(type*)(vector_generic_pop_back(vector, sizeof(vector.data[0]))))
/* This one is tricky, if 'value' is a constant, it's address cannot be taken.
I don't know if any better workarround is possible. */
#define vector_push_const(vector, type, value) \
{ \
type temp = value; \
vector_generic_push_back(vector, &temp, sizeof(vector.data[0]));\
}
/* Equivalent macro, but for pushing variables instead of constants */
#define vector_push_var(vector, value) vector_generic_push_back(vector, &value, sizeof(vector.data[0]))
/* Super-macro rediriging to constant or variable version of push_back depending on the context */
#define GET_MACRO(_1,_2,_3,NAME,...) NAME
#define vector_push_back(...) GET_MACRO(__VA_ARGS__, vector_push_const, vector_push_var)(__VA_ARGS__)
/* This macro isn't really needed, but just for homogenity */
#define vector_descroy(vector) vector_generic_destroy(vector)
The functions can then be used as you said in the example you linked, with the significant exception of vector_generic_push_back where unfortunately the type has to be specified each time as an extra macro argument.
So with this solution
You only have to do VECTOR_DEFINITION() within the .c file, avoiding the risk of declaring it with the same type twice
The vector library is only existing once in the binary
The macros can be used elegantly without using the type in their names, except for the pop back macro and the push literal macro.
If this is a problem you could make the push literal use long long always, it will work but potentially loose efficiency.
Similarly you could make the pop_back() macro and the vector_generic_pop_back() functions not return anything like they does in the C++ language, so that if you do both of those tricks you never need to use the type name explicitly in the macros.
As a reference, the main function you posted in the example that is linked in your question has to be adapted like that :
#include <stdio.h>
#include <stdlib.h>
#include "vector.h"
typedef unsigned int uint;
typedef char* str;
VECTOR_DEFINITION(uint)
VECTOR_DEFINITION(str)
int main()
{
vector_uint_t vector;
vector_init(&vector, 10);
for (unsigned int i = 0; i < vector.size; ++i)
vector.data[i] = i;
for (unsigned int i = 0; i < 10; ++i)
vector_push_back(&vector, i);
/* When pushing back a constant, we *have* to specity the type */
/* It is OK to use C keywords as they are supressed by the preprocessor */
vector_push_back(&vector, unsigned int, 12);
for (unsigned int i = 0; i < vector.size; ++i)
printf("%d ", vector.data[i]);
printf("\n");
vector_destroy(&vector);
vector_str_t sentence;
vector_init(&sentence, 0);
vector_push_back(&sentence, "Hello");
vector_push_back(&sentence, str, "World!"); /* Also possible, less efficient */
vector_push_back(&sentence, "How");
vector_push_back(&sentence, "are");
vector_push_back(&sentence, "you?");
for (unsigned int i = 0; i < sentence.size; ++i)
printf("%s ", sentence.data[i]);
printf("\n");
vector_destroy(&sentence);
return 0;
}

suggest:
remove the prototypes from the vector.h file.
place the prototypes at the top of the vector.def file.
remove the typedef struct from the vector.h file
place the typedef struct before the prototypes in the vector.def file.
then multiples #include statements for the vector.h file will have no bad effects.
Then use the following, in each source file that is to use these vector types:
#include<vector.h>
#define TYPE int
#include<vector.def>
#undef TYPE
#define TYPE char
#include<vector.def>
#undef TYPE
... etc
BTW:
There is no library involved, so I'm a bit confused by the reference
to 'library' in the question
It may be worthwhile to also prefix the 'static' modifier
to each of the function definitions so the definitions are
not visible across source files
It may be worthwhile to use parens around the parameters to TOKENPASTE
so modifiers like 'static' and.or 'const'
can be prefixed to the function names.

Related

What is the specific issue with this function in C [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]);

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]);

Passing array to function changes function 'sizeof(array)' [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]);

How to interpret the nested function calls using macros in C

I came across macro definition like below. Is the definition of the macro RVS_E(_I, _E) valid?
And how does the macro RVS_C() work (as it is dependent on RVS_E) and what would be the output of RVS_C
extern unsigned int rvs_trace_port;
/* Instrumentation point */
void RVS_Ipoint(unsigned int);
/* Instrumentation macros and functions */
#define RVS_I(_I) (rvs_trace_port = (_I))
#define RVS_E(_I,_E) ((void)RVS_I((_I)),(_E))
#define RVS_C(_I,_C) (RVS_E(_I,0)?(_C):(_C))
#define RVS_T(_I) RVS_E((_I),1)
#define RVS_F(_I) RVS_E((_I),0)
unsigned int RVS_CM (unsigned int * k, unsigned int pos, unsigned int b);
unsigned int RVS_DM (unsigned int id, unsigned int * k, unsigned int b);
#define RVS_DML RVS_DM
Following is the example code where these macros are used (it is an autogenerated "instrumented" code and hence looks a bit crazy)
if ( ( rvs_tmp_k_362=0, RVS_DM(362,&rvs_tmp_k_362,(unsigned int)(RVS_CM(&rvs_tmp_k_362,2,(unsigned int)((nvHist_Queue.DataPtr != (uint8*)&nvHist_QData)))
{
.....
}

Typechecking macro arguments in C

Is it possible to typecheck arguments to a #define macro? For example:
typedef enum
{
REG16_A,
REG16_B,
REG16_C
}REG16;
#define read_16(reg16) read_register_16u(reg16); \
assert(typeof(reg16)==typeof(REG16));
The above code doesn't seem to work. What am I doing wrong?
BTW, I am using gcc, and I can guarantee that I will always be using gcc in this project. The code does not need to be portable.
gcc supports typeof
e.g. a typesafe min macro taken from the linux kernel
#define min(x,y) ({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; })
but it doesn't allow you to compare two types. Note though the pointer comparison which Will generate a warning - you can do a typecheck like this (also from the linux kernel)
#define typecheck(type,x) \
({ type __dummy; \
typeof(x) __dummy2; \
(void)(&__dummy == &__dummy2); \
1; \
})
Presumably you could do something similar - i.e. compare pointers to the arguments.
The typechecking in C is a bit loose for integer-related types; but you can trick the compiler by using the fact that most pointer types are incompatible.
So
#define CHECK_TYPE(var,type) { __typeof(var) *__tmp; __tmp = (type *)NULL; }
This will give a warning, "assignment from incompatible pointer type" if the types aren't the same. For example
typedef enum { A1,B1,C1 } my_enum_t;
int main (int argc, char *argv) {
my_enum_t x;
int y;
CHECK_TYPE(x,my_enum_t); // passes silently
CHECK_TYPE(y,my_enum_t); // assignment from incompatible pointer type
}
I'm sure that there's some way to get a compiler error for this.
This is an old question, But I believe I have a general answer that according to Compiler Explorer apears to work on MSVC, gcc and clang.
#define CHECK_TYPE(type,var) { typedef void (*type_t)(type); type_t tmp = (type_t)0; if(0) tmp(var);}
In each case the compiler generates a useful error message if the type is incompatible. This is because it imposes the same type checking rules used for function parameters.
It can even be used multiple times within the same scope without issue. This part surprises me somewhat. (I thought I would have to utilize "__LINE__" to get this behavior)
Below is the complete test I ran, commented out lines all generate errors.
#include <stdio.h>
#define CHECK_TYPE(type,var) { typedef void (*type_t)(type); type_t tmp = (type_t)0; if(0) tmp(var);}
typedef struct test_struct
{
char data;
} test_t;
typedef struct test2_struct
{
char data;
} test2_t;
typedef enum states
{
STATE0,
STATE1
} states_t;
int main(int argc, char ** argv)
{
test_t * var = NULL;
int i;
states_t s;
float f;
CHECK_TYPE(void *, var); //will pass for any pointer type
CHECK_TYPE(test_t *, var);
//CHECK_TYPE(int, var);
//CHECK_TYPE(int *, var);
//CHECK_TYPE(test2_t, var);
//CHECK_TYPE(test2_t *, var);
//CHECK_TYPE(states_t, var);
CHECK_TYPE(int, i);
//CHECK_TYPE(void *, i);
CHECK_TYPE(int, s); //int can be implicitly used instead of enum
//CHECK_TYPE(void *, s);
CHECK_TYPE(float, s); //MSVC warning only, gcc and clang allow promotion
//CHECK_TYPE(float *, s);
CHECK_TYPE(float, f);
//CHECK_TYPE(states_t, f);
printf("hello world\r\n");
}
In each case the compiler with -O1 and above did remove all traces of the macro in the resulting code.
With -O0 MSVC left the call to the function at zero in place, but it was rapped in an unconditional jump which means this shouldn't be a concern. gcc and clang with -O0 both remove everything except for the stack initialization of the tmp variable to zero.
No, macros can't provide you any typechecking. But, after all, why macro? You can write a static inline function which (probably) will be inlined by the compiler - and here you will have type checking.
static inline void read_16(REG16 reg16) {
read_register_16u(reg16);
}
Building upon Zachary Vander Klippe's answer, we might even go a step further (in a portable way, even though that wasn't a requirement) and additionally make sure that the size of the passed-in type matches the size of the passed-in variable using the "negative array length" trick that was commonly used for implementing static assertions in C (prior to C11, of course, which does provide the new _Static_assert keyword).
As an added benefit, let's throw in some const compatibility.
#define CHECK_TYPE(type,var) \
do {\
typedef void (*type_t) (const type);\
type_t tmp = (type_t)(NULL);\
typedef char sizes[((sizeof (type) == sizeof (var)) * 2) - 1];\
if (0) {\
const sizes tmp2;\
(void) tmp2;\
tmp (var);\
}\
} while (0)
Referencing the new typedef as a variable named tmp2 (and, additionally, referencing this variable, too) is just a method to make sure that we don't generate more warnings than necessary, c.f., -Wunused-local-typedefs and the like. We could have used __attribute__ ((unused)) instead, but that is non-portable.
This will work around the integer promotion "issue" in the original example.
Example in the same spirit, failing statements are commented out:
#include <stdio.h>
#include <stdlib.h>
#define CHECK_TYPE(type,var) \
do {\
typedef void (*type_t) (const type);\
type_t tmp = (type_t)(NULL);\
typedef char sizes[((sizeof (type) == sizeof (var)) * 2) - 1];\
if (0) {\
const sizes tmp2;\
(void) tmp2;\
tmp (var);\
}\
} while (0)
int main (int argc, char **argv) {
long long int ll;
char c;
//CHECK_TYPE(char, ll);
//CHECK_TYPE(long long int, c);
printf("hello world\n");
return EXIT_SUCCESS);
}
Naturally, even that approach isn't able to catch all issues. For instance, checking signedness is difficult and often relies on tricks assuming that a specific complement variant (e.g., two's complement) is being used, so cannot be done generically. Even less so if the type can be a structure.
To continue the idea of ulidtko, take an inline function and have it return something:
inline
bool isREG16(REG16 x) {
return true;
}
With such as thing you can do compile time assertions:
typedef char testit[sizeof(isREG16(yourVariable))];
No. Macros in C are inherently type-unsafe and trying to check for types in C is fraught with problems.
First, macros are expanded by textual substitution in a phase of compilation where no type information is available. For that reason, it is utterly impossible for the compiler to check the type of the arguments when it does macro expansion.
Secondly, when you try to perform the check in the expanded code, like the assert in the question, your check is deferred to runtime and will also trigger on seemingly harmless constructs like
a = read_16(REG16_A);
because the enumerators (REG16_A, REG16_B and REG16_C) are of type int and not of type REG16.
If you want type safety, your best bet is to use a function. If your compiler supports it, you can declare the function inline, so the compiler knows you want to avoid the function-call overhead wherever possible.

Resources