this post was submitted on 28 Jun 2023
6 points (100.0% liked)

Programming

43 readers
1 users here now

This magazine is dedicated to discussions on programming languages, software development, and coding. Whether you are a beginner programmer or an experienced developer, this is the place for you. Here you can share your knowledge, ask questions, and engage in discussions on topics such as coding languages, software engineering, web development, and more. From the latest trends and frameworks to tips and tricks for debugging, this category covers a wide range of topics related to programming.

founded 2 years ago
 

Suppose that I have two features in my C program, feature foo and feature bar. I wish to be able to switch what features will be compiled into my program at compile time. The only two ways I know of doing this are:

  1. Using preprocessor directives
#define MYPROG_FEATURE_FOO 1
#define MYPROG_FEATURE_BAR 1

/* ... */

#if MYPROG_FEATURE_FOO == 1
/* code related to feature foo */
#else
/* code to prompt people to pay for the absolutely proprietary version of my program */
#endif

/* ... */

#if MYPROG_FEATURE_BAR == 1
/* code related to feature bar */
#else
/* code to prompt people to pay for the absolutely proprietary version of my program */
#endif

/* ... */

  1. Using the normal if with a const, non-volatile variable
const _Bool myprog_feature_foo = 1;
const _Bool myprog_feature_bar = 1;

/* ... */

if (myprog_feature_foo)
{
  /* code related to feature foo */
}
else
{
  /* buy proprietary version or no feature for you >:) */
}

/* ... */

if (myprog_feature_bar)
{
  /* code related to feature bar */
}
else
{
  /* buy proprietary version or no feature for you >:) */
}

/* ... */

What's the better way to do this? Is there a third way to achieve this that I have missed that's better than the above two?

top 4 comments
sorted by: hot top controversial new old
[–] [email protected] 4 points 2 years ago

Another way would be to keep the proprietary code in their own compilation units, and replace them with a dummy/stub implementation from your build system at config time (e.g. CMake option + if() statement). One benefit to this is that you don't have to litter your codebase with a bunch of preprocessor directives.

There's no "better" way though, just pick the one you find easier to manage.

[–] [email protected] 3 points 2 years ago (1 children)

Between those two options, use the preprocessor directives; otherwise go with @alejandro's sugestion. The latter solution incurs a constant cost at runtime and includes code in the executable that should never be run. Preprocessor directives would completely omit the respective feature's code preventing any possibility of access, without them the feature could actually be enabled via memory scanners (something I myself have abused).

[–] [email protected] 1 points 1 year ago* (last edited 1 year ago)

I'm no C expert, so take this with a grain of salt, but wouldn't any reasonable optimizing compiler remove the constant check at compile-time?

Of course, this is not guaranteed and depends on the compiler flags, so preproc should be preferred if compile-time is desired.

[–] qtip 1 points 2 years ago

Where appropriate, I split code like this into separate files (I like to have similarly named files in separate directories) with multiple build configurations. I'll tell the build system to compile different files for each configuration. I like this because it keeps the code clean and avoids using the preprocessor

load more comments
view more: next ›