Aurélien Pierre
Aurélien Pierre

Reputation: 713

define a 2D constant array in a C macro

I would like to load a static array in memory, used as a convolution kernel in a later loop, in C99 and later. I tried that:

/** This is the outer product of
 * filter[5] = { 1.0f / 16.0f, 4.0f / 16.0f, 6.0f / 16.0f, 4.0f / 16.0f, 1.0f / 16.0f };
 * computed at once, outside of the pixels loops, saving 25 multiplications per pixel
 * */
#define filter[5][5] { {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f}, \
                       {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
                       {0.02343750f, 0.093750f, 0.1406250f, 0.093750f, 0.02343750f}, \
                       {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
                       {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f} }

GCC 8 complains:

error: expected expression before « { » token
 #define filter { {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f}, \

I have found how to load 1D vectors, but how to do that with 2D ?

Edit

The ultimate goal is to build a SIMD array from it:

static const __m128 filter_sse[5][5] = { { _mm_set1_ps(filter[0][0]),
                                         ... },
                                           ... };

and using a static const float filter[5][5] makes it complain about trying to set a constant with non-constant values.

Upvotes: 1

Views: 1506

Answers (2)

0___________
0___________

Reputation: 67835

Abstracting from the sense of it

#include <stdio.h>

#define myfilter(name) name[5][5] = { {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f}, \
                       {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
                       {0.02343750f, 0.093750f, 0.1406250f, 0.093750f, 0.02343750f}, \
                       {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
                       {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f} }

int main()
{
    const float myfilter(filter1);
    printf("%f\n", filter1[1][1]);

    return 0;
}

Upvotes: 3

Craig Estey
Craig Estey

Reputation: 33631

You left off the = between filter[5][5] and { {.

And, as you have it, filter can't be be the macro name because it is followed by the brackets

And, you need the type (e.g. float)

Here's a cleaned up version:

#define DEFME float filter[5][5] = { \
    {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f}, \
    {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
    {0.02343750f, 0.093750f, 0.1406250f, 0.093750f, 0.02343750f}, \
    {0.01562500f, 0.062500f, 0.0937500f, 0.062500f, 0.01562500f}, \
    {0.00390625f, 0.015625f, 0.0234375f, 0.015625f, 0.00390625f} }

DEFME;

Side note: But, why use a macro for this?

Upvotes: 4

Related Questions