I've just noticed that an answer I have given for this question actually doesn't work:
Regardless of using CMake or not, the following should work with the current standard:
std::string resource = R"( #include "text.txt" )";
I thought that the pre-processor would recognize the #include "text.txt"
statement in first place and expand the text.
But that's obviously not the case, the result for
std::cout << resource << std::endl;
is
#include "text.txt"
I tried to use some macro to let the #include
statement be expanded within, but it doesn't work either:
#include <string>
#include <iostream>
#define RESOURCE_DEFINIION(resource_var,resource_name) \
const std::string resource_var = R"xxx( \
#include resource_name \
)xxx";
RESOURCE_DEFINIION(resource,"text.txt")
int main()
{
std::cout << resource << std::endl;
return 0;
}
The output is
\ #include resource_name \
Here's the demo to play with
Is there any trickery available to pull in the text.txt
resource into a c++-11 raw-string literal, using the pre-processor or any other regular c++ language feature?
Disclaimer:
I well know what's wrong with the above samples and why these fail this way. It's a problem that the pre-processor ignores the stuff appearing within "
pairs.
So is there a way to escape these to be seen by the pre-processor?
A "string literal" is a sequence of characters from the source character set enclosed in double quotation marks (" "). String literals are used to represent a sequence of characters which, taken together, form a null-terminated string. You must always prefix wide-string literals with the letter L.
Raw string literals are string literals that are designed to make it easier to include nested characters like quotation marks and backslashes that normally have meanings as delimiters and escape sequence starts. They're useful for, say, encoding text like HTML.
The compiler scans the source code file, looks for, and stores all occurrences of string literals. It can use a mechanism such as a lookup table to do this. It then runs through the list and assigns the same address to all identical string literals.
Python raw string is created by prefixing a string literal with 'r' or 'R'. Python raw string treats backslash (\) as a literal character. This is useful when we want to have a string that contains backslash and don't want it to be treated as an escape character.
It seems like not possible in standard C++
Problem 0: Only standard way of textual inclusion is #include
directive.
Problem 1: String literal is a preprocessing token, which are recognised in phase 3, so when preprocessing directives are executed in phase 4, it is already determined that #include
is a part of string literal and not a preprocessing directive.
preprocessing-token:
header-name
identifier
pp-number
character-literal
user-defined-character-literal
string-literal
user-defined-string-literal
preprocessing-op-or-punc
each non-white-space character that cannot be one of the above
Problem 2: It is impossible to bring preprocessing directive in source and execute it by macro substitution:
16.3.4/3
The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one
So you cannot have working #include
inside macro.
Problem 3: macro replacement list should be a valid preprocessing token:
control-line:
# define identifier replacement-list new-line
replacement-list:
pp-tokens opt
pp-tokens:
preprocessing-token
pp-tokens preprocessing-token
And string literal is a preprocessing token itself, you cannot build string literal from several macro.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With