I was trying to implement the sizeof() operator, and wanted the macro to return the result like the one provided by C lang.
I implemented it using gcc construct '()' like:
#define SIZEOF(type)\
({\
int result;\
type *p = 0;\
result = (char*)(p+1)-(char*)p;\
result;\
})
And used it like this:
x = SIZEOF(double);
Is there any way to do it without using gcc construct and returning value from that?
The best i can think of is pass another parameter to macro and store result in that like:
#define SIZEOF(type,result)\
do{\
type *p = 0;\
result = (char*)(p+1)-(char*)p;\
}while(0)
I know that I can replace this macro with inline function which will do the work but was looking for something in macro context. Is there any way to achieve this?
#define SIZEOF(type) (long int) (((type*)0) + 1)
Related
uint32_t fail_count = 0;
...
if(is_failed)
if(fail_count < UINT32_MAX - 1 )
++fail_count;
It works fine, but this code is fragile. Tomorrow, I may change the type of fail_count from uint32_t to int32_t and I forget to update UINT32_MAX.
Is there any way to assert fail_count is a uint32_t at the function where I have written my ifs?
P.S. 1- I know it is easy in C++ but I'm looking for a C way.
P.S. 2- I prefer to use two asserts than relying on the compiler warnings. Checking the number size via sizeof should work but is there any way to distinguish if type is unsigned?
As of C11, you can use a generic selection macro to produce a result based on the type of an expression. You can use the result in a static assertion:
#define IS_UINT32(N) _Generic((N), \
uint32_t: 1, \
default: 0 \
)
int main(void) {
uint32_t fail_count = 0;
_Static_assert(IS_UINT32(fail_count), "wrong type for fail_count");
}
You could of course use the result in a regular assert(), but _Static_assert will fail at compile time.
A better approach could be dispatching the comparison based on type, again using generic selection:
#include <limits.h>
#include <stdint.h>
#define UNDER_LIMIT(N) ((N) < _Generic((N), \
int32_t: INT32_MAX, \
uint32_t: UINT32_MAX \
) -1)
int main(void) {
int32_t fail_count = 0;
if (UNDER_LIMIT(fail_count)) {
++fail_count;
}
}
As you mentioned GCC, you can use a compiler extension to accomplish this in case you are not using C11:
First write a macro that emulates the C++ is_same. And then call it with the types you want to compare.
A minimal example for your particular case:
#include<assert.h>
#define is_same(a, b) \
static_assert(__builtin_types_compatible_p(typeof(a), typeof(b)), #a " is not unsigned int")
int main()
{
int fail_count = 0;
is_same(fail_count, unsigned int);
}
The compiler asserts:
<source>: In function 'main':
<source>:4:3: error: static assertion failed: "fail_count is not unsigned int"
static_assert(__builtin_types_compatible_p(typeof(a), typeof(b)), #a " is not unsigned int")
^~~~~~~~~~~~~
<source>:9:5: note: in expansion of macro 'is_same'
is_same(fail_count, unsigned int);
^~~~~~~
See Demo
What about a low-tech solution that works even with K&R C and any compiler past and present?
Place the right comment in the right place:
/*
* If this type is changed, don't forget to change the macro in
* if (fail_count < UINT32_MAX - 1) below (or file foobar.c)
*/
uint32_t fail_count = 0;
With a proper encapsulation this should refer to exactly one place in the code.
Don't tell me you increment the fail count in many places. And if you do, what
about a
#define FAIL_COUNT_MAX UINT32_MAX
right next to the declaration? That's more proper and clean code anyway.
No need for all the assertion magic and rocket sciencery :-)
Here is an example:
#define get_i() i
int i;
int i2;
i2 = get_i();
In the case above ^^^ get_i() acts like a function that returns something(the value ofi in this case).
#define set_i(value) do{i = (value);}while(0)
set_i(i2);
This ^^^ above acts like a function that DO NOT return.
My question is, can I use macros to create a function-like macro that can both, do something, and return an object? Here is a pseudo code:
#define increse_i2_and_return_i() i2++; return i;
Is that possible?
You can use comma operator for that. The value of the last operand will be the value of an entire expression.
#define increse_i2_and_return_i() (i2++, i)
The downside of this trick is that you can't create temporary variables in a such macro.
I have implemented my custom sizeof operator as below
#define my_sizeof(x) do{\
typeof(x) _a;\
(char*)(&_a + 1) - (char*)(&_a);\
}while(0)
If I compile it I get the error
test.c:26:22: error: expected expression before ‘do’
Can't figure out what I am doing wrong.
My main function is given below.
int main()
{
int a;
unsigned long long b;
double c;
printf("size of a %zd \n",my_sizeof(a));
printf("size of b %zd \n",my_sizeof(b));
printf("size of c %zd \n",my_sizeof(c));
return 0;
}
Your macro expands to a do loop. A do loop is not an expression, and does not produce a value. The compiler is telling you that you cannot use a do loop where you are trying to use one, and it is right.
There is no clean alternative in C, since you cannot declare a variable inside an expression.
This is because of the way you macro is preprocessed. The preprocessor output (which you may get using gcc -E file.c) will look like this (stripped for a variable only):
int main() {
int a;
printf("size of a %zd \n", do { typeof(a) _a; (char*)(&_a + 1) - (char*)(&_a); } while (0));
return 0;
}
which is not a correct C syntax. You could use do..while macro like that though (without an assignment or nesting it inside another function):
MY_MACRO(x);
Refer to this article for some more information.
A do/while loop can't return a value. You could instead use a GCC-style statement expression to do what you're trying:
#define my_sizeof(x) ({ \
typeof(x) _a; \
(char*)(&_a + 1) - (char*)(&_a); \
})
Clang & GCC support statement expressions for sure, I don't know about any other compilers off the top of my head.
This question already has answers here:
Implementing a generical 'map' function over arrays in C
(3 answers)
Closed 10 years ago.
how can i define a general map operation on an array in C?
ideally I want something like python's map(function,array) ~~ but as a macro. I believe this would be something like C++'s std::transform, but would be in C, and not use iterators..
(this would be unary operation)
I was thinking something like:
template <class T*, class U*,size_t N>
T* map(T (*func)(U), U* arr,size_t N)
{
T* tmp = (T*)malloc(sizeof(T) * N);
size_t i;
for(i=0;i<N;i++)
{
*(tmp+i) = *func(*(arr+i));
}
}
... but of course templates are in C++..
so how can I 1) do the latter and 2) if you could, could you fix the above code snippet.
Thanks
For a template like this, there is a fairly straightforward translation to macros; the major syntactic wrinkle is that you can't return the result array, the variable to write it to has to be another parameter.
#define map(func_, input_, output_, type_, n_) do { \
output_ = xmalloc(sizeof(type_) * (n_)); \
size_t i_; \
for (i_ = 0; i_ < (n_); i_++) \
output_[i_] = func_(input_[i_]); \
} while (0)
This is not as type-unsafe as it looks, provided you pay attention to your compiler warnings. However, it is not particularly safe if any of the actual arguments to a use of this macro isn't a simple identifier. Most importantly, catastrophic things will happen if any of the actual arguments has side effects.
This can be cured, as can the inability to return the result array, but only if you're willing to use GNU extensions...
#define gnumap(func_, input_, type_, n_) ({ \
__typeof(func_) func__ = (func_); \
__typeof(input_) input__ = (input_), \
output__ = xmalloc(sizeof(type_) * n__); \
__typeof(n_) n__ = (n_), \
i__; \
for (i__ = 0; i__ < n__; i__++) \
output__[i__] = func__(input__[i__]); \
/* return */ output__; \
})
Would I do either of these in real life? Probably not, but sometimes it really is the least bad available option. Think of it as one step shy of rewriting that critical inner loop in assembly language.
(xmalloc, in case you're unfamiliar with it, is the conventional name for a user-written wrapper around malloc that either succeeds or crashes the entire program. I use it here to dodge the question of how to cope with malloc failing.)
So, you could write a function that takes a function pointer and a void * (or char *) to the data, and a data-size.
I certainly wouldn't use only macros to do this, but you may have a macro that doe something like:
#define MAP(func, type, arr, size) map(func, sizeof(type), arr, size)
and map is the function I describe above.
Are there any builtin equivalents to _countof provided by other compilers, in particular GCC and Clang? Are there any non-macro forms?
Using C++11, the non-macro form is:
char arrname[5];
size_t count = std::extent< decltype( arrname ) >::value;
And extent can be found in the type_traits header.
Or if you want it to look a bit nicer, wrap it in this:
template < typename T, size_t N >
size_t countof( T ( & arr )[ N ] )
{
return std::extent< T[ N ] >::value;
}
And then it becomes:
char arrname[5];
size_t count = countof( arrname );
char arrtwo[5][6];
size_t count_fst_dim = countof( arrtwo ); // 5
size_t count_snd_dim = countof( arrtwo[0] ); // 6
Edit: I just noticed the "C" flag rather than "C++". So if you're here for C, please kindly ignore this post. Thanks.
Update: C++ 17 support std::size() (defined in header <iterator>)
You can use boost::size() instead:
#include <boost/range.hpp>
int my_array[10];
boost::size(my_array);
I'm not aware of one for GCC, but Linux uses GCC's __builtin_types_compatible_p builtin to make their ARRAY_SIZE() macro safer (it'll cause a build break if applied to a pointer):
/* &a[0] degrades to a pointer: a different type from an array */
#define __must_be_array(a) \
BUILD_BUG_ON_ZERO(__builtin_types_compatible_p(typeof(a), typeof(&a[0])))
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
Note: I think the BUILD_BUG_ON_ZERO() macro has a misleading name (it causes a build failure if the expression is not zero and returns 0 otherwise):
/* Force a compilation error if condition is true, but also produce a
result (of value 0 and type size_t), so the expression can be used
e.g. in a structure initializer (or where-ever else comma expressions
aren't permitted). */
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
I think the naming for this macro comes from looking at it in two parts: BUILD_BUG_ON is what the macro does when the expression is true, and ZERO is the value 'returned' by the macro (if there's not a build break).
This?
#define _countof(a) (sizeof(a)/sizeof(*(a)))