define string at compiler options - c++

Using Tornado 2.2.1 GNU
at C/C++ compiler options I'm trying to define string as follow:
-DHELLO="Hello" and it doesn't work (it also failed for -DHELLO=\"Hello\" and for -DHELLO=\\"Hello\\" which works in other platforms)
define value -DVALUE=12 works without issue.
does anybody know to proper way to define string in Tornado?

The problem with such a macro is, that it normally isn't a string (in the C/C++ sense), just a preprocessor symbol. With numbers it works indeed, because preprocessor number can be used in C/C++ as is, but with string symbols, if you want to convert them to C/C++ strings (besides adding the escaped quotes) you need to "stringize" them.
So, this should work (without extra escaped quotes):
#define _STRINGIZE(x) #x
#define STRINGIZE(x) _STRINGIZE(x)
string s = STRINGIZE(HELLO)
(note the double expansion to get the value of the macro stringized, i.e. "Hello", instead of the macro name itself, i.e. "HELLO")

Related

How to stringize string with trailing backslash

When I build my C++ project the compiler generates this equivalent macro:
#define SOLUTION_DIR "c:\dev\my_project\"
In a normally #defined macro the trailing escaped double quotes would trigger compiler errors due to the unterminated string but compiler can do whatever it wants and makes this available to the code literally even if the string is invalid.
The usual way to expand macro values to C strings:
#define STRINGIZE( x ) #x
#define EXPAND( x ) STRINGIZE( x )
doesn't work in this case due to the unterminated string passed as argument.
std::string s = EXPAND( SOLUTION_DIR );
...
error: newline in constant
Is there a way to extract the string value of this macro and use it in my code equivalent to:
std::string str = R"(c:\dev\my_project\)";
where R is raw character prefix described here https://en.cppreference.com/w/cpp/language/string_literal
Notes:
I tried re-writing these macros using the R prefix to avoid escaping
the final quote mark but couldn't get to a functional version.
I can tell the compiler to define SOLUTION_DIR string without the
surrounding quotes, but I can't avoid the trailing backslash. In
this case however I get other warnings and errors due to the unknown
escape sequences (\d) and the fact that the trailing
backslash is taken to indicate that the macro is continuing on
the next line.
Update:
Here's the context for those who think something is broken and needs to be fixed.
I use Visual Studio 2019 (VS). In the project properties "C++/Preprocessor/Preprocessor Definitions" one can define various macros in the format:
NAME1=VALUE1;NAME2=VALUE2;...
which are then made available at compile time as
#define NAME1 VALUE1
#define NAME2 VALUE2
VS generates a number of predefined macros (not C++ but build environment macros) for various directories and other values (debug/release, 32 or 64 bit etc). They take the form $(Name) and are set to some string value such as:
$(Configuration) Debug
$(SolutionDir) C:\dev\some_project\
They are used to create location independent project settings such as the temp or binary output directories, or set the correct environment for whatever version of the project is being built (for instance Debug/x64).
In my case I need to get a hold of the current solution path directly in my code, and using the $(SolutionDir) VS macro seemed the easiest way to do it.
So here's how I defined my SOLUTION_PATH macro in "Properties/Preprocessor/Preprocessor Definitions":
SOLUTION_DIR="$(SolutionDir)
which translates into the compile time macro described initially:
#define SOLUTION_DIR "c:\dev\my_project\"
However, by default many macros that expand to paths, including $(SolutionDir), contain a trailing backslash which can't be removed hence the "broken" macro above.
Generally an executable binary doesn't need to and should not know anything about its build directories, so the path related macros are not necessarily designed to be used to define C++ macros, and the trailing backslash is not an issue. But my project needs that information because it itself triggers other build actions that depend on the current environment.
So this is not a malfunction of any of the components, everything works as designed, it just happens that for my specific project it would be very useful to be able to do things this way, even if it's non-standard.
I was able to make this work by adding a trailing ".":
SOLUTION_DIR="$(SolutionDir)."
which results in the equivalent:
#define SOLUTION_DIR "C:\dev\my_project\."
which points to the same directory and now compiles with no errors.

Can you use C/C++ preprocessor tokens in multiline string literals

Extending on this question and this question , is it possible to have a multiline string literal using either the preprocessor method shown or C++ multiline string literals that contain the values of a preprocessor symbol. For example:
#define SOME_CONSTANT 64
#define QUOTE(...) #__VA_ARGS__
const char * aString = QUOTE(
{
"key":"fred",
"value":"SOME_CONSTANT"
}
);
Ideally I want "SOME_CONSTANT" to be replaced with "64".
I have tried using all the tricks in my limited skill set including stringizing and have had no luck.
Any ideas?
You have two problems. The first is that preprocessor tokens inside quotes (i.e. string literals) aren't substituted. The second is that you must defer the actual stringification until all preprocessing tokens have been replaced. The stringification must be the very last macro that the preprocessor deals with.
Token substitution happens iterativly. The preprocessor deals with the substitution, and then goes back to see if there is anything left to substitute in the sequence it just replaced. We need to use it to our advantage. If we have an hypothetical TO_STRING macro, we need the very next iteration to substitute all preprocessing tokens, and only the one after that to produce a call to the "real" stringification. Fortunately, it's fairly simple to write:
#define TO_STRING(...) DEFER(TO_STRING_)(__VA_ARGS__)
#define DEFER(x) x
#define TO_STRING_(...) #__VA_ARGS__
#define SOME_CONSTANT 64
#define QUOTE(...) TO_STRING(__VA_ARGS__)
const char * aString = QUOTE({
"key":"fred",
"value": TO_STRING(SOME_CONSTANT)
});
Live example
We need the DEFER macro because the preprocessor won't substitute inside something that it recognizes as an argument to another macro. The trick here, is that the x in DEFER(TO_STRING_)(x) is not an argument to a macro. So it's substituted in the same go as DEFER(TO_STRING_). And what we get as a result is TO_STRING_(substituted_x). That becomes a macro invocation in the next iteration. So the preprocessor will perform the substitution dictated by TO_STRING_, on the previously substituted x.

L_ macro in glibc source code

I was reading through the source code of glibc and I found that it has two macros which have the same name
This one is on the line 105
#define L_(Str) L##Str
and this on the line 130
#define L_(Str) Str
What do these macros really mean ? The usage is only for comparing two characters
For example on line 494, you could see it is used for comparing character values between *f and '$'
if(*f == L_('$')). If we wanted to compare the two characters, we could have compared them directly, instead of directing them through a macro ? Also, what is the use case for the macro on line 105 ?
It prepends macro argument with L prefix (wchar_t literal - it uses as large datatype as is needed to represent every possible character code point instead of normal 8 bit in char type) if you're compiling wscanf version of function (line 105). Otherwise it just passes argument as it is (line 130).
## is string concatenation operator in c preprocessor, L##'$' will expand to L'$' eventually.
To sum up: it is used to compile two, mutually exclusive versions of vscanf function - one operating on wchar_t, one on char.
Check out this answer: What exactly is the L prefix in C++?
Let's read the code. (I have no idea what it does, but I can read code)
First, why are there two defines as you point out? One of them is used when COMPILE_WSCANF is defined, the other is used otherwise. What is COMPILE_WSCANF? If we look further down the file, we can see that different functions are defined. When COMPILE_WSCANF is defined, the function we end up with (through various macros) is vfwscanf otherwise we get vfscanf. This is a pretty good indication that this file might be used to compile two different functions one for normal characters, one for wide characters. Most likely, the build system compiles the file twice with different defines. This is done so that we don't have to write the same file twice since both the normal and wide character functions will be pretty similar.
I'm pretty sure that means that this macro has something to do with wide characters. If we look at how it's used, it is used to wrap character constants in comparisons and such. When 'x' is a normal character constant, L'x' is a wide character constant (wchar_t type) representing the same character.
So the macro is used to wrap character constants inside the code so that we don't have to have #ifdef COMPILE_WSCANF.

Should I use _T or _TEXT on C++ string literals?

For example:
// This will become either SomeMethodA or SomeMethodW,
// depending on whether _UNICODE is defined.
SomeMethod( _T( "My String Literal" ) );
// Becomes either AnotherMethodA or AnotherMethodW.
AnotherMethod( _TEXT( "My Text" ) );
I've seen both. _T seems to be for brevity and _TEXT for clarity. Is this merely a subjective programmer preference or is it more technical than that? For instance, if I use one over the other, will my code not compile against a particular system or some older version of a header file?
A simple grep of the SDK shows us that the answer is that it doesn't matter—they are the same. They both turn into __T(x).
C:\...\Visual Studio 8\VC>findstr /spin /c:"#define _T(" *.h
crt\src\tchar.h:2439:#define _T(x) __T(x)
include\tchar.h:2390:#define _T(x) __T(x)
C:\...\Visual Studio 8\VC>findstr /spin /c:"#define _TEXT(" *.h
crt\src\tchar.h:2440:#define _TEXT(x) __T(x)
include\tchar.h:2391:#define _TEXT(x) __T(x)
And for completeness:
C:\...\Visual Studio 8\VC>findstr /spin /c:"#define __T(" *.h
crt\src\tchar.h:210:#define __T(x) L ## x
crt\src\tchar.h:889:#define __T(x) x
include\tchar.h:210:#define __T(x) L ## x
include\tchar.h:858:#define __T(x) x
However, technically, for C++ you should be using TEXT() instead of _TEXT(), but it (eventually) expands to the same thing too.
Commit to Unicode and just use L"My String Literal".
From Raymond Chen:
TEXT vs. _TEXT vs. _T, and UNICODE vs. _UNICODE
The plain versions without the
underscore affect the character set
the Windows header files treat as
default. So if you define UNICODE,
then GetWindowText will map to
GetWindowTextW instead of
GetWindowTextA, for example.
Similarly, the TEXT macro will map to
L"..." instead of "...".
The versions with the underscore
affect the character set the C runtime
header files treat as default. So if
you define _UNICODE, then _tcslen will
map to wcslen instead of strlen, for
example. Similarly, the _TEXT macro
will map to L"..." instead of "...".
What about _T? Okay, I don't know
about that one. Maybe it was just to
save somebody some typing.
Short version: _T() is a lazy man's _TEXT()
Note: You need to be aware of what code-page your source code text editor is using when you write:
_TEXT("Some string containing Çontaining");
TEXT("€xtended characters.");
The bytes the compiler sees depends on the code page of your editor.
Here's an interesting read from a well-known and respected source.
Similarly, the _TEXT macro will map to L"..." instead of "...".
What about _T? Okay, I don't know about that one. Maybe it was just to save somebody some typing.
These macros are a hold over from the days when an application might have actually wanted to compile both a unicode and ANSI version.
There is no reason to do this today - this is all vestigial. Microsoft is stuck with supporting every possible configuration forever, but you aren't. If you are not compiling to both ANSI and Unicode (and no one is, let's be honest) just go to with L"text".
And yes, in case it wasn't clear by now: _T == _TEXT
I've never seen anyone use _TEXT() instead of _T().
Neither. In my experience there are two basic types of string literals, those that are invariant, and those that need to be translated when your code is localized.
It's important to distinguish between the two as you write the code so you don't have to come back and figure out which is which later.
So I use _UT() for untranslatable strings, and ZZT() (or something else that is easy to search on) for strings that will need to be translated. Instances of _T() or _TEXT() in the code are evidence of string literals that have not yet be correctly categorized.
_UT and ZZT are both #defined to _TEXT
Use neither, and also please don't use the L"..." crap.
Use UTF-8 for all strings, and convert them just before passing to microsoft APIs.

How to use wide string literals in c++ without putting L in front of each one

You'll have to forgive my ignorance, but I'm not used to using wide character sets in c++, but is there a way that I can use wide string literals in c++ without putting an L in front of each literal?
If so, how?
No, there isn't. You have to use the L prefix (or a macro such as _T() with VC++ that expands to L anyway when compiled for Unicode).
The new C++0x Standard defines another way of doing this:
http://en.wikipedia.org/wiki/C%2B%2B0x#New_string_literals
on a related note..
i'm trying to do the following
#define get_switch( m ) myclass::getSwitch(L##m)
which is a macro the will expand
get_switch(isrunning)
into
myclass::getswitch(L"isrunning")
this works fine in c++ visualstudio 2008
but when i compile the same code under mac Xcode (for iphone) i get the error:
error: 'L' was not defined in this scope.
EDIT: Solution
#define get_switch( m ) myclass::getSwitch(L ## #m)
this works on both vc++ and mac xcode (gcc)
Why do you not want to prefix string literals with an L? It's quite simple - strings without an L are ANSI strings (const char*), strings with an L are wide-character strings (const wchar_t*). There is the TEXT() macro, which makes a string literal into an ANSI or a wide-character string depending on of the current project is set to use Uncode:
#ifdef UNICODE
#define TEXT(s) L ## s
#else
#define TEXT(s) s
#endif
There's also the _T() macro, which is equivalent to TEXT().