4

I have some code that looks like this:

struct mystruct
{
    /* lots of members */
};

void mystruct_init( struct mystruct* dst, int const condition )
{
    if ( condition )
    {
        /* initialize members individually a certain way */
    }
    else
    {
        /* initialize members individually another way */
    }
}

Options I'm considering:

  • Simplest would be to have a function that assigns to every member and call that. Should I simply hope the compiler optimizes that call away?
  • Define a macro to explicitly avoid the function call overhead.
  • Write everything the long way.

What is the proper way to handle such a scenario in C11?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
user2296177
  • 2,807
  • 1
  • 15
  • 26
  • There's nothing wrong with what you have. Readability is important. You could hoist some of the lines out, e.g. `dst->foo = condition ? 5 : 7;` but consider which option makes it more obvious to the reader what is going on and why. – M.M Aug 25 '16 at 05:07
  • 1
    Consider using 'compound literals' and 'designated initializers': `*dst = (struct mystruct) { .member1 = value1, .member2 = value2, … };` in each branch of the `if`. – Jonathan Leffler Aug 25 '16 at 05:30
  • If the `struct` needs to be `const`, you could create a number of macros containing different initializer lists, then `#ifdef` between them. Not pretty, but there's no other option then. – Lundin Aug 25 '16 at 11:37

3 Answers3

7

Just write a function that initializes a member, or if you want (opinion based), use a MACRO.

By the way, I would personally do it like this:

void mystruct_init( struct mystruct* dst, int const condition )
{
    if ( condition )
        init_first_way(..);
    else
        init_second_way(..);
}

or just use the ternary operator. Remember, you care about readability and always have in mind:

Simplicity is a virtue!


I really think worrying about optimization at this stage will make a victim of immature optimization, since I doubt it will be the bottleneck.

In general, if you want to optimize your code, profile your code(while it runs with optimization flags, many people do not know this, I was one of them: Poor performance of stl list on vs2015 while deleting nodes which contain iterator to self's position in list), find the bottleneck and try to optimize that bottleneck.

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 3
    +1 for mentioning `immature optimization`. As said, premature optimization is the source of all evil :) [http://c2.com/cgi/wiki?PrematureOptimization] – Arun Aug 25 '16 at 05:20
  • @Arun It was less about optimization and more about conciseness. I'm not very familiar with compiler optimizations, so I didn't want to needlessly have something that was less efficient. Thank you both for pointing that out though, it reminds me to stop worrying about things like that when I haven't even measured. – user2296177 Aug 25 '16 at 05:22
  • @user2296177 been there, done that, see my edit. I feel the wind that made you ask that question though, that's why I upvoted. – gsamaras Aug 25 '16 at 05:35
7

I do not think that there is any clear rule here. To me, it depends on the taste of the author.

Two obvious ways are:

// initialize members that are independent of 'condition'

if (condition) {
  // initialize members one way
}
else {
  // initialize members another way
}

The same may be written as:

// initialize members that are independent of 'condition'

// initialize members based on 'condition'
dst->memberx = condition ? something : something_else;
// ...

Please do not worry about one function call overhead.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Arun
  • 19,750
  • 10
  • 51
  • 60
4

I agree with the answers already posted (@gsamaras and @Arun). I just wanted to show another approach that I have found useful a couple of times.

The approach is to make some constants with the two (or more) relevant initialization values and then make a simple assignment based on one (or more) conditions.

Simple example:

#include<stdio.h>
#include <string.h>

struct mystruct
{
  int a;
  float b;
};

const struct mystruct initializer_a = { 1, 3.4 };
const struct mystruct initializer_b = { 5, 7.2 };

int main (void)
{
  int condition = 0;
  struct mystruct ms = condition ? initializer_a : initializer_b;
  printf("%d %f\n", ms.a, ms.b);
  return 1;
}
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63