Search code examples
c++c++11c-preprocessorconstexprstring-literals

Concat two `const char` string literals


Is it possible to concat two string literals using a constexpr? Or put differently, can one eliminate macros in code like:

#define nl(str) str "\n"

int main()
{
  std::cout <<
      nl("usage: foo")
      nl("print a message")
      ;

  return 0;
}

Update: There is nothing wrong with using "\n", however I would like to know whether one can use constexpr to replace those type of macros.


Solution

    1. Yes, it is entirely possible to create compile-time constant strings, and manipulate them with constexpr functions and even operators. However,

    2. The compiler is not required to perform constant initialization of any object other than static- and thread-duration objects. In particular, temporary objects (which are not variables, and have something less than automatic storage duration) are not required to be constant initialized, and as far as I know no compiler does that for arrays. See 3.6.2/2-3, which define constant initialization, and 6.7.4 for some more wording with respect to block-level static duration variables. Neither of these apply to temporaries, whose lifetime is defined in 12.2/3 and following.

    So you could achieve the desired compile-time concatenation with:

    static const auto conc = <some clever constexpr thingy>;
    std::cout << conc;
    

    but you can't make it work with:

    std::cout <<  <some clever constexpr thingy>;
    

    Update:

    But you can make it work with:

    std::cout << *[]()-> const {
                 static constexpr auto s = /* constexpr call */;
                 return &s;}()
              << " some more text";
    

    But the boilerplate punctuation is way too ugly to make it any more than an interesting little hack.


    (Disclaimer: IANALL, although sometimes I like to play one on the internet. So there might be some dusty corners of the standard which contradicts the above.)

    (Despite the disclaimer, and pushed by @DyP, I added some more language-lawyerly citations.)