2

Consider the following statements

typedef struct {
    int member1;
    int member2;
}Custom_t;

void ISR(void) 
{
    static Custom_t struct1[SOME_CONSTANT];
    ......
    ......
}

How can I initialize all member2 variable to a single value in C programming?

If I iniatilize the structure like the one shown below, then there is chance of somebody changing the "SOME_CONSTANT" in a header file and forgetting to update the list.

Another solution would be to give the structure a global scope for the current file. But the only function which uses the structure is the ISR().

void ISR(void) 
{
    static Custom_t struct1[SOME_CONSTANT] = {
        {0, 3},
        {0, 3},
        ......
        ......
    };
    ......
    ......
}

Is there any method to solve this problem in C?

6
  • what compiler are you using? There may be shortcuts depending on the type of compiler. Commented Jul 9, 2018 at 8:44
  • 2
    Maybe you can't initialize in a generic way, but you can add an assertion that SOME_CONSTANT matches the size of your array. Commented Jul 9, 2018 at 8:48
  • See also stackoverflow.com/q/51241228/15168 Commented Jul 9, 2018 at 8:53
  • @pm101 I am using a microcontroller IDE(Keil uVision) for Cortex-M series microcontroller. Commented Jul 9, 2018 at 8:59
  • 1
    something in the same vein as BOOST_PP_REPEAT might be interesting to experiment with (macro's there should be C compatible). Commented Jul 9, 2018 at 9:03

4 Answers 4

2

You can use Designated Initializers and do it in this way:

#include <stdio.h>

#define SOME_CONSTANT 30

typedef struct {
    int member1;
    int member2;
} Custom_t;

int main(void)
{
    static Custom_t struct1[SOME_CONSTANT] = 
    {
        [0 ... SOME_CONSTANT - 1].member2 = 30
    };


    printf("%d\n", struct1[25].member2);
    printf("%d\n", struct1[19].member2);
    printf("%d\n", struct1[0].member2);

    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

1

How about to add hard-coded compiling time checking against SOME_CONSTANT in the .c file (e.g. right before the initializer)?

#if SOME_CONSTANT != <some_hard_code_value>
#error "SOME_CONSTANT is not equal to <some_hard_code_value>"
#endif

The rational of this "hard-code" is whenever the SOME_CONSTANT is changed, the initializer need be updated, as well as the compiling time checking.

1 Comment

In case SOME_CONSTANT is a member of an enumeration this will cause an error. But a _Static_assert will always work in a way that makes sense. Depends on C11 being available of course.
1

You don't need to specify the array size in advance, you can compute it later:


static Custom_t struct1[] = {
        {0, 3},
        {0, 3},
        {13,3},
    };
#define SOME_CONSTANT (sizeof struct1 /sizeof struct1[0])

or: use __LINE__ to compute the number of elements.

3 Comments

This is a good idea. But here is the problem. the size of the structure depends on the no.of sensors attached to it.
And for each sensor you'll need to specify a line in the initializer anyway.
I might be wrong,as I usually am, but I can not see any problems with this answer, you have got the number of elements within the array.
0

I've had to do something like this with projects with a configurable number of sensors :

[custom_t.h]

typedef struct {
    int member1;
    int member2;
}Custom_t;

#define MAX_CUSTOM_T 4

Custom_t *new_Custom_t (int member1, int member2);

[custom_t.c]

#include "custom_t.h"

static Custom_t g_Customt[MAX_CUSTOM_T];
static uint8 g_numCustom_t = 0;

Custom_t *new_Custom_t (int member1, int member2)
{
    if ( g_numCustom_t < MAX_CUSTOM_T )
    {
       Custom_t *new_obj = &g_Customt[g_numCustom_t++];
       new_obj->member1 = member1;
       new_obj->member1 = member2;

       return new_obj;
    }
    else
    {
        // throw exception?
        // or go into while(1)?
        // or software breakpoint if debug?
        // or just...
        return NULL;
    }
}

[main.c]

#include "custom_t.h"

Custom_t *myCustom1; 
Custom_t *myCustom2; 
Custom_t *myCustom3; 

somefunc()
{
    myCustom1 = new_Custom_t (0,3);
    myCustom2 = new_Custom_t (1,3);
    myCustom3 = new_Custom_t (2,3);

   // do stuff
}

It means if you want to create a new one, you may or may not need to update MAX_CUSTOM_T depending on its size already, but will just have to add a new line call to new_Custom_t(int,int). A Disadvantage though is it is slightly complex for what you might need, and if you ever want to add more members to initialize, you'll need to update the parameters passed into the new_ function to suit. This can be done instead with a sending a single separate structure for parameters rather than multiple parameters (a bit like MPLAB harmony).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.