std::accumulate alternative for the C programming language I've come up with some simple implementation for algorithms in C and more specifically for std::accumulate alternate since I need something like it recently. Can you provide some review on the approach?
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;


#define ARRSIZE(X) (sizeof(X) / sizeof(X[0]))


#define ACCUMULATE(RET, FIRST, LAST, INIT, SUM_CB)      \
    do {                                                \
        RET = INIT;                                     \
        while (FIRST != LAST){                          \
            RET = SUM_CB(RET, *FIRST);                  \
            FIRST++;                                    \
        }                                               \
    } while(0);

/**
 * example usage
 * sum integers and sum strings by some delimiter
*/
struct str_t
{
    char data[512];
};



struct str_t sumStr(struct str_t a, struct str_t b)
{
    struct str_t ret = {0};
    strcat(ret.data, a.data);
    strcat(ret.data, &quot;--&quot;);
    strcat(ret.data, b.data);
    return ret;
}


struct A { int a, b, c; };

struct A sumA(struct A a, struct A b) {
    struct A ret ;
    ret.a = a.a + b.a;
    ret.b = a.b + b.b;
    ret.c = a.c + b.c;
    return ret;
}


int main()
{
    unsigned long i;

    struct A sumvec[10];
    struct str_t sumstr[10];
    memset(sumstr, 0, sizeof(sumstr));

    for(i=0; i &lt; ARRSIZE(sumvec); i++) {
        sumvec[i].a = i;
        sumvec[i].b = i+1;
        sumvec[i].c = i+2;
        snprintf(sumstr[i].data, sizeof(sumstr[i].data), &quot;%d&quot;, i);
    }

    for(i=0; i &lt; ARRSIZE(sumvec); i++) {
        printf(&quot;[%d][%d][%d]\r\n&quot;, sumvec[i].a ,sumvec[i].b,sumvec[i].c);
    }


    struct A ret = {sumvec[0].a, sumvec[0].b, sumvec[0].c};
    struct A* pBegin = &amp;sumvec[1];
    struct A* pEnd = &amp;sumvec[ARRSIZE(sumvec)];

    ACCUMULATE(ret, pBegin, pEnd,  ret, sumA)

    printf(&quot;SUM: [%d][%d][%d]\r\n&quot;, ret.a, ret.b, ret.c);


    struct str_t retstr;
    strcat(retstr.data, sumstr[0].data);

    struct str_t *pBegs = &amp;sumstr[1];
    struct str_t *pEnds = &amp;sumstr[ARRSIZE(sumstr)];

    ACCUMULATE(retstr, pBegs, pEnds, retstr, sumStr);

    printf(&quot;SUM STR: [%s]\r\n&quot;, retstr.data);
    return 0;
}
When using the do { ... } while (0) idiom for macros, we don't generally include the terminating semicolon in the definition.  That's so we can use it like a function call:
if (condition)
    ACCUMULATE(result, a, b, 0, add);
else
    ACCUMULATE(result, a, c, 10, add);

There's a typo in the ARRSIZE() macro: where we protect X from misbinding - should be (X)[0], not (X[0]):
#define ARRSIZE(X) (sizeof (X) / sizeof (X)[0])

Also, be careful with this macro when its argument isn't a whole, completely defined array.  In particular, it will be wrong when the argument is a variable-length (dynamically-allocated) array, or when the argument is a pointer (perhaps the array decayed to pointer - that can easily catch you out!).
In the sample usage:

Identifiers ending in _t are reserved for future use by the standard library, so str_t should be renamed.
It's a shame, after being so careful to use snprintf() avoid overflow, that we  we then use unchecked strcat();strcat();strcat(); in sumStr()  - why not snprintf() there, too?
A lot of needless parens around the arguments to sizeof.  Just write sizeof sumstr instead of sizeof(sumstr), for example.