Home > front end >  #define or constexpr, which is more suitable here to maximal efficiency?
#define or constexpr, which is more suitable here to maximal efficiency?

Time:09-02

I have a constant string value

std::string name_to_use = "";

I need to use this value in just one place, calling the below function on it

std::wstring foo (std::string &x) {...};
// ...
std::wstring result = foo (name_to_use);

I can simply not declare the variable and use a string literal in the function call instead, but to allow easy configuration of name_to_use I decided to declare at the beginning of the file.

Now, since I am not really modifying name_to_use I thought why not use a #define preprocessing directive so I do not have to store name_to_use as a const anywhere in memory while the main program runs continuously (a GUI is displayed).

It worked fine, but then I came across constexpr. A user on stackoverflow has said to use it instead of #define as it is a safer option.

However, constexpr std::string name_to_use is still going to leak memory in this case right? Since it's not actually replacing occurrences of name_to_use with a value but holding a reference to it computed at compile time (which does not offer me any benefit here anyway, if I'm not mistaken?).

CodePudding user response:

If you #define it to "", then at each call there'll be a conversion from c-string to std::string, which is pretty inefficient. However, you can (usually) pass macro defines as arguments to compiler, which helps customization. Even in that case, it makes sense to write the static constexpr std::string name_to_use.

With static constexpr std::string name_to_use = ...;, the problem of conversion goes away (likely done compile-time). Don't expect the compiler not to do optimizations - if it's a compile-time string, it might happen that the entire function is optimized away (but still, the object will exists and the code will adhere to the as-if rule).

To combine the two, you can do:

#ifdef NAME_TO_USE
constexpr const std::string = # NAME_TO_USE;
#else
constexpr const std::string = "";
#endif

Also, as others said, please consider std::string_view to avoid allocation.

CodePudding user response:

The user is saying well, and you did understand right.

Using the constexpr method will allocate a constant when the macro will just replace itself at compile time. The only benefit of the first is that it is typed, and can make your code a little bit safer when you compile it.

This being said, the choice is yours. Do you want to have a non-typed macro that doesn't add any operation on run-time, or a typed constant that use a little bit of memory at parsing ?

  • Related