Skip to content

Instantly share code, notes, and snippets.

@LukeGary462
Created March 7, 2023 21:23
Show Gist options
  • Select an option

  • Save LukeGary462/ce9d56e1583be067fa5de0496a172490 to your computer and use it in GitHub Desktop.

Select an option

Save LukeGary462/ce9d56e1583be067fa5de0496a172490 to your computer and use it in GitHub Desktop.
C foreach macro implementation
// test
// https://paiza.io/projects/gckklFp-m9gy5nT3pGsFKw
// stack overflow source
// https://stackoverflow.com/questions/400951/does-c-have-a-foreach-loop-construct
#include <stdio.h>
#include <stdint.h>
#define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
#define FOREACH(_item_, _array_) \
for(size_t i = 0u, _keep_ = 1u; \
_keep_ && i < COUNTOF(_array_); \
_keep_ = !_keep_, i++) \
for (_item_ = _array_[i]; _keep_; _keep_ = !_keep_)
/** test 1 **/
typedef struct {
unsigned int val;
char *name;
}my_type_t;
my_type_t objList[] = {
{.val=1u, .name="name1"},
{.val=2u, .name="name2"},
{.val=3u, .name="name3"},
{.val=4u, .name="name4"},
};
/************/
/** test 2 **/
int intArray[] = {-1,0,1,2};
/************/
/** test 3 **/
typedef void ((*module_method_t)(char *argv[], int argc));
typedef struct {
char *name;
module_method_t method;
} module_obj_t;
void module_method_1(char *argv[], int argc);
void module_method_2(char *argv[], int argc);
void module_method_3(char *argv[], int argc);
void module_method_1(char *argv[], int argc){
printf("Method 1 execute\n");
}
void module_method_2(char *argv[], int argc){
printf("Method 2 execute\n");
}
void module_method_3(char *argv[], int argc){
printf("Method 3 execute\n");
}
module_obj_t moduleList[] = {
{.name="Module 1", .method=module_method_1},
{.name="Module 2", .method=module_method_2},
{.name="Module 3", .method=module_method_3},
};
/************/
int main(void){
printf("Test 1: FOREACH macro with custom data objects ...\n");
FOREACH(my_type_t item, objList){
printf("name = %s,\tval = %u\n",
item.name, item.val
);
}
printf("\nTest 2: FOREACH macro with integer array ...\n");
FOREACH(int item, intArray){
printf("value = %d\n", item);
}
printf("\nTest 3: FOREACH macro with list of objects that contain function pointers ...\n");
FOREACH(module_obj_t item, moduleList){
printf("Module Name = %s\n\t", item.name);
(void)item.method(NULL, 0);
}
}
@donausoft
Copy link

donausoft commented May 9, 2025

Great.
Would it also be posible to access the index? Something like:

#define FOREACH(_index_, _item_, _array_)

I tried it myself, but can't get it to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment