0

We can concatenate adjacent string literals like so:

puts( "ABC" "DEF" );

However, MSVC fails with a strange error when I try to do this:

puts( ("ABC") ("DEF") );

Which means I can do a single computation outputting a string literal like so:

puts( NUM_ELEMENTS>125?"WARNING":"OK" )

But I can't concatenate the string literals output from multiple of these, such as:

#define SOME_SETTING 0x0B //I sometimes wish there were binary literals
#define BIT_STR(x,n) ((x>>n)&1?"1":"0")
#define BIT_STR4(x) BIT_STR(x,3) BIT_STR(x,2) BIT_STR(x,1) BIT_STR(x,0)

...

puts( "Initializing some hardware setting: " BIT_STR4(SOME_SETTING) );

EDIT: So my question is... what is the correct way to concatenate compile time computed string literals?

  • 1
    So what is the question? – Cory Klein Jul 11 '13 at 15:43
  • Possible duplicate of http://stackoverflow.com/questions/308695/c-string-concatenation – Cory Klein Jul 11 '13 at 15:44
  • 1
    `(x&1?"1":"0")` is computed at runtime, not at compile-time. So compile-time concatenation won't help with it. – interjay Jul 11 '13 at 15:44
  • @interjay I think it can be computed at compile time if `SOME_SETTING` is constant. Nevertheless, its result isn't qualified for string concatenation any longer. – glglgl Jul 11 '13 at 15:46
  • if everything is a constant, the math should be done at compile time, right? – SlowProgrammer Jul 11 '13 at 15:48
  • @SlowProgrammer If everything is a constant, the math *can* and *may* be done at compile time. It *may* depend on your optimization settings, and there *may* even be cases where the compiler chooses not to, if the expression is complex enough, even though it's entirely constant... – twalberg Jul 11 '13 at 16:09
  • @twalberg I can't imagine writing a parser that would stop in the middle of evaluation and emit code. Can you think of an example that actually doesn't explicitly refer to runtime information (like functions) but still doesn't complete the calculation at compile time? (Or maybe I misunderstood and your comment was just saying that the specs don't _require_ the compiler to do this, even though any major one like gcc, msvc, etc. would?) – SlowProgrammer Jul 11 '13 at 16:22
  • @Cory Klein, can you remove the duplicate tag? What you listed is related only in that it is about string concatenation, but what you listed is regarding runtime concatenation where-as this is about compile time concatenation. – SlowProgrammer Jul 11 '13 at 16:24
  • @SlowProgrammer I was actually getting at the fact that it's not required by the spec. I can't off the top of my head think of examples where modern compilers would choose not to do the compile-time calculcations if they could - if such examples did exist, they would probably be contrived non-useful monstrosities. But the possibility exists that a compiler writer could choose to defer certain computations until runtime. Perhaps in some stripped-down fast but still "compliant" compilers - something like [this](http://bellard.org/tcc/) (but I don't know that that's necessarily true of TCC)... – twalberg Jul 11 '13 at 16:27
  • @SlowProgrammer - The question as is specifically only refers to concatenation of compile time computed string literals. It doesn't refer to "compile time concatenation". As is, it is still a duplicate. Either way, I can't remove a flag once placed. – Cory Klein Jul 11 '13 at 16:31
  • @Cory Klein, okay that reading makes sense. Thanks for explaining, and I changed the title (even if the flag can't be removed, might as well make my intent clearer :) ). Thanks. – SlowProgrammer Jul 11 '13 at 16:47

1 Answers1

2

BIT_STR(SOME_SETTING, 3), to take an example, can indeed be computed on runtime: it results to (0?"1":"0"), which in turn results to a pointer to a constant string "0", not to a string literal any longer.

String literals can be concatenated, constant pointers to constant strings can't. That's the difference.

glglgl
  • 89,107
  • 13
  • 149
  • 217
  • YES! Seems so obvious now. Any idea of how to concatenate string constants then? – SlowProgrammer Jul 11 '13 at 15:59
  • In other words, this doesn't answer the question. Although it does help me understand the error of my naive approach, and thank you for that. – SlowProgrammer Jul 11 '13 at 16:08
  • 1
    The answer is, you can't do it that way. If you have to concatenate strings that are computer at runtime, you need to use `strcpy()`, or `strcat()`, or `sprintf()`, or something similar. – This isn't my real name Jul 11 '13 at 19:54
  • @Elchonon Edelson, you missed the point. I am not trying to concatenate strings that are computed at runtime. I am trying to concatenate strings that come from math on constant literals, and therefore everything is available to the compiler at compile time. – SlowProgrammer Jul 11 '13 at 21:59
  • It looks like this may be possible in gcc, following some ideas at http://stackoverflow.com/questions/9912214/concatenate-string-literal-with-char-literal However MSVC doesn't support that (and due to the way the macro is written, I'm not convinced his solution avoids runtime evaluation since it uses multiple statements ... although the optimizer could likely clean that up.) – SlowProgrammer Jul 11 '13 at 22:02
  • 1
    Ah, I see. You're trying to concatenate a string and an expression that yields a pointer to a string constant, and you're expecting that since all the values are available at compile time, that even though the resulting expression is not a macro, the compiler should evaluate the expression during translation and replace it with the string constant, and that it should do this during the process of string literal concatenation. You're trying to mix translation phase seven into the middle of translation phase six. I'm fairly sure you can't do that. – This isn't my real name Jul 12 '13 at 03:36