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.
Related
I am trying to write a macro which returns the smallest value of several integers. When I compile the following code, it throws an error "expected expression". I don't know what's wrong there. Could anyone point out the issues with this code?
#define SMALLEST (nums, (ret_val), ...) \
do { \
int i, val; \
va_list vl; \
va_start(vl,nums); \
(*ret_val) = va_arg(vl, int); \
for (i = 1; i < nums; i++) \
{ \
val=va_arg(vl, int); \
if ((*ret_val) > val) \
(*ret_val) = val; \
} \
va_end(vl); \
} while(0)
int main ()
{
int nums = 3;
int ret_val = 0;
SMALLEST(nums, &ret_val, 1, 2, 3);
return 0;
}
I am just curious about how to do it with Macro.
I am just curious about how to do it with Macro.
You can't. va_list is a way for a variadic function to access its arguments. What you have written is a variadic macro. They are not the same (in particular the variadic macro is still only a syntactic convenience that does not let you process individual arguments). The only way to do what you want is to call a variadic function of your own design inside the variadic macro (and then you might as well eliminate the macro).
However, if you really insist on using a variadic macro, it turns out that you are lucky that the same separator , is used in macro arguments and in array initializers, so you can try something like:
#define F(X, ...) \
do { \
int t[] = { __VA_ARGS__ }; \
for (int i = 0; i < sizeof t / sizeof t[0]; i++) \
… \
} while (0)
I don't think you can. From the gcc manual (https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html) the best you can do in a standard way is write __VA_ARGS__, which will expand the arguments in place (for example to pass to a function).
It then goes on to define other non-standard extensions, which you might be able to use, but wouldn't be standard.
Why not do it with a function?
The way you deal with argument lists in variadic macros is not the same as the way you deal with them in variadic functions. Instead of using va_list and its related macros, you use __VA_ARGS__.
That is pretty much the extent of it: you cannot write a macro that processes variadic list from the beginning to the end; you are limited to passing the arguments through to a variadic function, which performs the actual processing.
Note: Your implementation is incorrect, too: you should be using va_start(vl,ret_val) instead of va_start(vl,nums), because you are supposed to pass the last argument before ... to va_start.
If I were to rewrite this as a function, though, I would drop the ret_val pointer, and make a function that returns a value the regular way.
It makes no sense to do that with macro. That's what functions are for.
You get an error because the SMALLEST symbol in your main function gets replaced by the whole body of the function you've defined. AFAIK you can't define a function inside another function in C.
Is there any particular reason why you want to use a macro here? You seem to be confusing macro syntax and standard syntax (the reason for your error).
You should use a function to achieve this - this is what a function is for. The following code should get you what you want:
int Smallest( int iNumberOfIntegers, ... )
{
va_list args = NULL;
int i = 0;
int iSmallestValue = 0;
int iCurrentValue = 0;
va_start( args, iNumberOfIntegers );
iSmallestValue = va_arg( args, int );
for(i = 0; i < iNumberOfIntegers - 1; i++)
{
iCurrentValue = va_arg( args, int );
if(iSmallestValue > iCurrentValue)
{
iSmallestValue = iCurrentValue;
}
}
return iSmallestValue;
}
Of note, you you need to pass the size of the variadic argument if you are going to loop over it in this manner. This is not necessary in format strings because the compiler can infer the number from the format string specifiers.
We subtract 1 from the loop to account for a 0 offset.
Edit: And, as others have said, you can't use a variadic macro in the way you were trying.
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)
I have a utility struct defined in a library API, that has four fields, all numeric counters.
typedef struct {
size_t bytes;
int codepoints;
int graphemes;
int columns;
} TickitStringPos;
I want to provide some utilities to easily work on these structures. I could implement these as (static inline) functions, such as
static inline void tickit_stringpos_zero(TickitStringPos *pos) {
pos->bytes = pos->codepoints = pos->graphemes = pos->columns = 0;
}
static inline void tickit_stringpos_limit_columns(TickitStringPos *pos, int columns) {
pos->bytes = pos->codepoints = pos->graphemes = -1;
pos->columns = columns;
}
TickitStringPos here, limit;
tickit_stringpos_zero(&here);
tickit_stringpos_limit_columns(&limit, 20);
Or I could implement these as macros, such as
#define TICKIT_STRINGPOS_ZERO(pos) do { \
(pos).bytes = (pos).codepoints = (pos).graphemes = (pos).columns = 0; \
} while(0);
#define TICKIT_STRINGPOS_LIMIT_COLUMNS(pos,_columns) do { \
(pos).bytes = (pos).codepoints = (pos).graphemes = -1; \
(pos).columns = _columns; \
} while(0);
TickitStringPos here, limit;
TICKIT_STRINGPOS_ZERO(here);
TICKIT_STRINGPOS_LIMIT_COLUMNS(limit, 20);
What should I consider weighing up these two approaches? Each are likely to be as powerful and flexible, but is one approach specifically preferable for some reason?
Prefer functions over macro for the simple reason that they provide you type safety unlike macros.
Also, with functions you don't have to take care of any side effects unlike macros.
As for the function being inline it is just an indication to the compiler of your wish it is not binding on the compiler to make the function inline, however any modern compiler will easily do the needful.
As Als said, I believe functions should be used when there is such a possibility, for maintanence reasons.Since they are inline, there is no performance loss.Save macros for constants, or maybe (extremely) small computations.
(note: the inline keyword makes a function be replaced in place, saving the context switching overhead but introducing space concerns.Unless you want to give space for speed, you can also use regular functions)
Macros are evaluated out of (before) the compiler scope and this is the main argument against those (being the second one that most of the times they're just unnecessary). You can find a good explanation by Bjarne Stroustrup himself here.
I have a function that I need to macro'ize. The function contains temp variables and I can't remember if there are any rules about use of temporary variables in macro substitutions.
long fooAlloc(struct foo *f, long size)
{
long i1, i2;
double *data[7];
/* do something */
return 42;
}
MACRO Form:
#define ALLOC_FOO(f, size) \
{\
long i1, i2;\
double *data[7];\
\
/* do something */ \
}
Is this ok? (i.e. no nasty side effect - other than the usual ones : not "type safe" etc). BTW, I know "macros are evil" - I simply have to use it in this case - not much choice.
There are only two conditions under which it works in any "reasonable" way.
The macro doesn't have a return statement. You can use the do while trick.
#define macro(x) do { int y = x; func(&y); } while (0)
You only target GCC.
#define min(x,y) ({ int _x = (x), _y = (y); _x < _y ? _x : _y; })
It would help if you explain why you have to use a macro (does your office have "macro mondays" or something?). Otherwise we can't really help.
C macros are only (relatively simple) textual substitutions.
So the question you are maybe asking is: can I create blocks (also called compound statements) in a function like in the example below?
void foo(void)
{
int a = 42;
{
int b = 42;
{
int c = 42;
}
}
}
and the answer is yes.
Now as #DietrichEpp mentioned it in his answer, if the macro is a compound statement like in your example, it is a good practice to enclose the macro statements with do { ... } while (0) rather than just { ... }. The link below explains what situation the do { ... } while (0) in a macro tries to prevent:
http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html
Also when you write a function-like macro always ask yourself if you have a real advantage of doing so because most often writing a function instead is better.
First, I strongly recommend inline functions. There are very few things macros can do and they can't, and they're much more likely to do what you expect.
One pitfall of macros, which I didn't see in other answers, is shadowing of variable names.
Suppose you defined:
#define A(x) { int temp = x*2; printf("%d\n", temp); }
And someone used it this way:
int temp = 3;
A(temp);
After preprocessing, the code is:
int temp = 3;
{ int temp = temp*2; printf("%d\n", temp); }
This doesn't work, because the internal temp shadows the external.
The common solution is to call the variable __temp, assuming nobody will define a variable using this name (which is a strange assumption, given that you just did it).
This is mostly OK, except that macros are usually enclosed with do { ... } while(0) (take a look at this question for explanations):
#define ALLOC_FOO(f, size) \
do { \
long i1, i2;\
double *data[7];\
/* do something */ \
} while(0)
Also, as far as your original fooAlloc function returns long you have to change your macro to store the result somehow else. Or, if you use GCC, you can try compound statement extension:
#define ALLOC_FOO(f, size) \
({ \
long i1, i2;\
double *data[7];\
/* do something */ \
result; \
})
Finally you should care of possible side effects of expanding macro argument. The usual pattern is defining a temporary variable for each argument inside a block and using them instead:
#define ALLOC_FOO(f, size) \
({ \
typeof(f) _f = (f);\
typeof(size) _size = (size);\
long i1, i2;\
double *data[7];\
/* do something */ \
result; \
})
Eldar's answer shows you most of the pitfalls of macro programming and some useful (but non standard) gcc extension.
If you want to stick to the standard, a combination of macros (for genericity) and inline functions (for the local variables) can be useful.
inline
long fooAlloc(void *f, size_t size)
{
size_t i1, i2;
double *data[7];
/* do something */
return 42;
}
#define ALLOC_FOO(T) fooAlloc(malloc(sizeof(T)), sizeof(T))
In such a case using sizeof only evaluates the expression for the type at compile time and not for its value, so this wouldn't evaluate F twice.
BTW, "sizes" should usually be typed with size_t and not with long or similar.
Edit: As to Jonathan's question about inline functions, I've written up something about the inline model of C99, here.
Yes it should work as you use a block structure and the temp variables are declared in the inner scope of this block.
Note the last \ after the } is redundant.
A not perfect solution: (does not work with recursive macros, for example multiple loops inside each other)
#define JOIN_(X,Y) X##Y
#define JOIN(X,Y) JOIN_(X,Y)
#define TMP JOIN(tmp,__LINE__)
#define switch(x,y) int TMP = x; x=y;y=TMP
int main(){
int x = 5,y=6;
switch(x,y);
switch(x,y);
}
will become after running the preprocessor:
int main(){
int x=5,y=6;
int tmp9 = x; x=y; y=tmp9;
int tmp10 = x; x=y; y=tmp10;
}
They can. They often shouldn't.
Why does this function need to be a macro? Could you inline it instead?
If you're using c++ use inline, or use -o3 with gcc it will inline all functions for you.
I still don't understand why you need to macroize this function.
I have this macro code, which allows me to define both a C enum and a list of the enumerated names as strings using one construct. It prevents me from having to duplicate enumerator names (and possibly introducing errors for large lists).
#define ENUM_DEFINITIONS(F) \
F(0, Item1) \
F(5, Item2) \
F(15, Item3) \
...
F(63, ItemN)
then:
enum Items {
#define ITEM_ENUM_DEFINE(id, name) name = id,
ENUM_DEFINITIONS(ITEM_ENUM_DEFINE)
#undef ITEM_ENUM_DEFINE
which, when expanded, should produce:
enum Items {
Item1 = 0,
Item2 = 5,
Item3 = 15,
...
ItemN = 63,
}
In the implementation file, I have this code:
const char* itemNames[TOTAL_ITEMS];
int iter = 0;
#define ITEM_STRING_DEFINE(id, name) itemNames[iter++] = #name;
ENUM_DEFINITIONS(ITEM_STRING_DEFINE)
#undef ITEM_STRING_DEFINE
which, when expanded, produces:
itemNames[iter++] = "Item1";
itemNames[iter++] = "Item2";
itemNames[iter++] = "Item3";
...
itemNames[iter++] = "ItemN";
I'd like to know how many enumerator items I've created in this fashion and be able to pass it to compile-time arrays. In the example above, this would be determining that TOTAL_ITEMS = N at compile-time. Is it possible to count macro invocations in this way?
I've seen mention of a non-standard COUNTER macro, similar to the FILE and LINE macros, but I'm hoping there is a more standard way.
Would also be interested in hearing if there is a better way to achieve this without having to use macros.
The following should work:
#define ITEM_STRING_DEFINE(id, name) #name, // note trailing comma
const char *itemNames[] = {
ENUM_DEFINITIONS(ITEM_STRING_DEFINE)
};
#define TOTAL_ITEMS (sizeof itemNames / sizeof itemNames[0])
Edit: Thank you to Raymond Chen for noting we don't have to worry about the unnecessary final comma in the list. (I had been misremenbering the problem for enums with strict C89 compilers, as in Is the last comma in C enum required?.)
You can use the same technique to count the invocations.
enum itemscounter {
#define ITEM_ENUM_DEFINE(id, name) name##counter,
ENUM_DEFINITIONS(ITEM_ENUM_DEFINE)
#undef ITEM_ENUM_DEFINE
TOTAL_ITEMS
};
Would also be interested in hearing if there is a better way to achieve this without having to use macros.
You could always use a scripting language such as ruby or python to generate .c and .h files for you. If you do it well, you can integrate your script into your Makefile.
I know this isn't a complete answer.
You can create a macro around something like this.
#include <stdio.h>
const char * array[] = {
"arr1", "arr2", "arr3", "arr4"
};
int main (int argc, char **argv)$
{
printf("%d\n", sizeof(array)/sizeof(const char *));
}
If you can modify your enum so it has continous elements you can do sth like this (from Boost)
enum { A=0,B,C,D,E,F,N };
const char arr[N]; // can contain a character for each enum value
See the suggestions Mu Dynamics 'Enums, Strings and Laziness'; these are at least related to what you're after.
Otherwise, look at the Boost Preprocessor collection (which is usable with the C preprocessor as well as the C++ preprocessor).