1

I have a header file that contains functions based upon the user OS, it does so using:

#ifdef _WIN32 // Windows
...
#else // Linux/Unix code (I know it will be either Windows or Linux/Unix)
...
#endif

The functions defined in their appropriate blocks are currently called from main at runtime and store a constant, but this got me thinking: Can I compute this constant in the header at compile?

Something like:

#ifdef _WIN32 
// function here; call it foobar()
#define WINCONST foobar()
#else
// function here; call it xfoobar()
#define NIXCONST xfoobar()
#endif

However I am not sure that you can use function calls in the #define preprocessor directive. I know that you can use it in a manner such as #define ADD(x, y) (x + y) but thats about it.

5
  • "However I am not sure that you can use function calls in the #define preprocessor directive" You can use anything at preprocessor directives that will be expanded to the appropriate text for you. Commented Jul 29, 2018 at 19:43
  • @pstatix maybe irrelevant but why would you do this? What not just precalculate wincost separate and just put the value here? Or is winconst itself not a constant and depends on more compiler variables not shown above? Commented Jul 29, 2018 at 20:20
  • @SiddharthChabra Both WINCONST and NIXCONST perform a calculation on a series of loops to determine the amount of user time a function spends on the users system. They are not going to be the same value for every user because some users may have a more advanced machine; so they should be computed at either run time or compile time. Commented Jul 29, 2018 at 23:22
  • @SiddharthChabra How do you "precalculate" something to store the constant when compiling? Commented Jul 30, 2018 at 2:41
  • @pstatix if it depends on user machines are you planning to complie the solution on each users machine separately? The minute you use a function like std::clock your expression is no longer constant. Commented Jul 30, 2018 at 6:54

1 Answer 1

3

Something like:

constexpr uint32_t foo()
{
    // complex calculations...
    return 0;
}

uint32_t const SomeConstant = foo();

Side note: foo will be evaluated to a compile time constant, as long as no non-compile-time arguments are passed to, so above definition then will result in a compile time constant as well (equivalent to uint32_t SomeConstant = 7;). However, code won't break if you remove constexpr qualification from foo unless you use the constant where compile time constants are required (e. g. array definitions). This may be desired or not, in latter case, constexpr provides stronger guarantees (i. e. compilation failure whenever foo(/*...*/) is not compile-time-constant):

uint32_t constexpr SomeConstant = foo();
Sign up to request clarification or add additional context in comments.

9 Comments

Not sure, but won't someConstant not being a constexpr mean that foo() does not have to be called during compilation time and thus it's constexprness will be useless in this example?
constexpr functions are evaluated at compile time whenever this is possible. So if parameters (so there are at all) are compile time constants, the result will be as well, ending in something equivalent to uint32_t SC = 7;, which is a compile time constant as well... (Side note: Matter changes if foo is not constexpr or called with non-compile-time-constant arguments.)
I think it would be best to replace const by constexpr, so that in the future, if foo becomes not constexpr anymore, we have a compilation error.
@aconcagua should it not be return some_const_val? If you return 0 it might as well be uint32_t const SomeConstant = 0?
"constexpr functions are evaluated at compile time whenever this is possible" is only a QoI issue, however, const integrals act like constexpr so it's fine but misleading here.
|

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.