Macro string: what does #define __T(x) x mean? And __T(#x)? - c++

What does this mean?
#define __T(x) x
Just return x?
I am seeing code using syntax I've not seen before:
#define CREATE_ENCODER(CODEC) \
strcpy(codecName, __T(#CODEC); \
pCodec = new CODEC##VideoEncoder();
if(parFileName) \
{ pEncoderParams = new CODEC##EncoderParams; \
}
What is the # for?

Actually __T is used to turn string to wchar_t* or char*, in tchar.h you have:
#define __T(x) L ## x
used when UNICODE is enabled and
#define __T(x) x
when it is disabled
If your code is to be compiled on both UNICODE and non-UNICODE compilations you use:
TCHAR* sz = __T("My text");
most WINAPI functions use TCHAR* or some of its form
Actually I prefer _T() version, never knew __T version exists, at the bottom of tchar.h you have it defined:
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
So back to your example:
strcpy(codecName, __T(#CODEC)); \
is equivalent to:
strcpy(codecName, "CODEC"); \
on NON-unicode build, and
strcpy(codecName, L"CODEC"); \
on UNICODE build
VERY IMPORTANT!!: using _T or __T is not really enough to make sure you code is UNICODE compilant. It will make it easier to call WINAPI functions. You must prepare your code to work with UNICODE.

Yes, that define is simply replaced with the passed value. This kind of define is often used if you e.g. want to determine at compile time if you want to pass a value through a translation function (#define __T(x) translate(x)) or not (#define __T(x) x).
# stringifies the passed value: http://gcc.gnu.org/onlinedocs/cpp/Stringizing.html and
## is the concatenation operator: http://gcc.gnu.org/onlinedocs/cpp/Concatenation.html

Related

How can I convert combined literal constant into wchar in compile time?

I have a combined literal constant defined in preprocessor macros such as
#define A "1"
#define B "3"
#define VERSION A "." B
Eventually I would like to convert it later to wchar_t * by using _T macro such as:
TCHAR * version = _T(VERSION);
However it fails to compile with Visual Studio 2013 runtime with the following error:
concatenating mismatched strings
It seems that it's fixed in newer versions and above code gets compiled with no problems using VS2015 runtime.
Any ideas how to make it work with VS2013 runtime?
They all need to be wide or narrow, try:
#define A L"1"
#define B L"3"
#define VERSION A L"." B
const wchar_t * version = VERSION;
Or
#define A "1"
#define B "3"
#define VERSION A "." B
const char * version = VERSION;
Edit: this one answers the comment
#define A "1"
#define B "3"
#define VERSION A "." B
#define EXPAND(x) _T(##x)
#define TO_WIDE(x) (EXPAND(x))
const wchar_t * version = TO_WIDE(VERSION);
Actually I didn't find a perfect solution. But I found how to modify creation of VERSION macro to be able to simply apply _T macro to it. The code is following:
#define MAJOR 3
#define MINOR 1
#define DOT .
#define __STR2(x) #x
#define __STR(x) __STR2(x)
#define _CONCAT3(s1, s2, s3) s1 ## s2 ## s3
#define CONCAT3(s1, s2, s3) _CONCAT3(s1, s2, s3)
#define VERSION_STR __STR(CONCAT3(MAJOR, DOT, MINOR))
and then
TCHAR * version = _T(VERSION);
works fine.

Using boost preprocessor for token comparison

I found a page that it is explained how identifier-token comparison can be implemented using c preprocessor directives. This could be done by some macros like this:
#define COMPARE_foo(x) x
#define COMPARE_bar(x) x
#define PRIMITIVE_COMPARE(x, y) IS_PAREN \
( \
COMPARE_ ## x ( COMPARE_ ## y) (()) \
)
PRIMITIVE_COMPARE(foo, bar) // expands to 0
PRIMITIVE_COMPARE(bar, bar) // expands to 1
Which IS_PAREN checks that it is completely expanded or not(which occurs just when two macros are different because of painting blue).
Now I am looking for a similar command in Boost Preprocessor. I want to have a list of accepted types of a macro and if the macro called with one of this type it expands to what it must otherwise it does not anything. My pseudo code is something like this:
#define ACCEPTED_TYPE (float)(int)(string)
#define Macro(x) // If one of accepted type do a otherwise do nothing
If boost preprocessor has not the exact solution what is your suggestion to make implementation easier.

Is there widely-available wide-character variant of `__FILE__`?

One may generally use __LINE__ and __FILE__ in C++ programs, with many toolchains, including GCC.
__LINE__ under GCC evaluates to an expression of type int;
__FILE__ evaluates to a char const[N] where N is the appropriate value.
Does any major toolchain provide an equivalent to __FILE__ with type wchar const[N]?
If so, what is it?
You can make your own WFILE:
#define WIDE2(x) L##x
#define WIDE1(x) WIDE2(x)
#define WFILE WIDE1(__FILE__)
Tested with non-ASCII characters and filename 马克.cpp:
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#define WIDE2(x) L##x
#define WIDE1(x) WIDE2(x)
#define WFILE WIDE1(__FILE__)
int main() {
_setmode(_fileno(stdout), _O_U16TEXT); // required for Unicode output to console
wprintf(L"%s\n", WFILE);
}
Demo (running from cmd.exe and Chinese language support installed):
C:\>cl /W4 /nologo 马克.cpp
马克.cpp
C:\>马克.exe
马克.cpp
Use:
WIDE(MEXPAND(__FILE__))
and
WIDE(STRINGIFY(__LINE__))
or replace __LINE__ with anything that needs to be stringified, and replace __FILE__ with any macro string literal you want to widen.
Using the following definitions:
#define STRINGIFY2(m) #m
#define MEXPAND(m) m
#define STRINGIFY(m) STRINGIFY2(m)
#define WIDE(m) L ## m
Example usage:
#define AssertBreakMethod DebugBreak
#define AssertBreakForce(expr) \
do \
{ \
if (!(expr)) \
{ \
OutputDebugStringW(WIDE(MEXPAND(__FILE__)) \
WIDE("(") WIDE(STRINGIFY(__LINE__)) \
WIDE("): Assertion failed: ") \
WIDE(#expr) WIDE("\n")); \
AssertBreakMethod(); \
} \
} \
while (0)
Note that the whole parameter to OutputDebugString is assembled statically at compile time into a single string literal.
The trick with stringification of a macro is passing it through another macro. When __FILE__ is passed to MEXPAND it is expanded at that time. MEXPAND returns its argument which is now a string. It is then legal to put the leading L there to make it wide.
STRINGIFY does the same trick, it passes its argument through STRINGIFY2 which expands the argument to the line number (which looks like an integer at that point) then STRINGIFY2 puts the # symbol before it, stringifying the integer.
In Visual Studio just surround it with _T(), for example:
TRACE( _T("function = %s"), _T(__FUNCTION__);
I would have put this answer as a comment to an earlier reply but was not allowed due to not having the minimum 50 reputation to comment...
In Visual Studio, _T(__FILE__) will NOT expand to L__FILE__ unless you modify its standard definition of _T in the tchar.h header file. _T(__FILE__) and _T(__FUNCTION__) worked 5 years ago and still work today if you are looking for wide versions of the current file and function.
_T(x) is defined as __T(x), which is defined as L##x when _UNICODE is defined and x otherwise. So _T(__FILE__) expands to something like __T("my_file.c"), which then expands to L"my_file.c" or "my_file.c" depending on _UNICODE. It is useful to test things before claiming that they do not work.
For example use const auto name = L"" __FUNCTION__;

__COUNTER__ in variable name

I have seen this question:
How to generate random variable names in C++ using macros?
with the following answer: https://stackoverflow.com/a/1675203/551045
And I've tried to implement it in clang.
Here is my declaration:
#define TRACE(stream) FuncTrace x#__COUNTER__ (llvm::errs(), "hallo", 1)
I tried all variations x##__COUNTER__; x ## __COUNTER__ and so on but none seem to work.
Could this be a clang bug? The clang help page says it has the __COUNTER__ macro.
In the end the macro I need something like this:
#define TRACE(stream) FuncTrace x#__COUNTER__ (stream, __FUNCTION__, __LINE__)
To concatenate two tokens into one you use the ## operator. The # operator is used to turn a token into a string.
x ## __COUNTER__ will just produce x__COUNTER__. You need to fully expand __COUNTER__ first. One possible method is add a few more indirections, e.g.
#define YTRACE(x, y) FuncTrace x##y (llvm::errs(), __FUNCTION__, __LINE__)
#define XTRACE(x, y) YTRACE(x, y)
#define TRACE(x) XTRACE(x, __COUNTER__)

error C2664: 'CComboBox::InsertString' : cannot convert parameter 2 from 'const char [4]' to 'LPCTSTR'

I am trying to do the following:
class sig
{
CComboBox objList;
void SetDefault();
}
void sig :: SetDefault()
{
objList.InsertString(0, METHOD_ONE);
}
I have defined METHOD_ONE in a different class as
#define METHOD_ONE "OFF"
And I get the above error.
Can somebody please help me?
Cheers,
Chintan
The most important part is to understand the error; know what is a const char [4], is the easy part but, what about the LPCTSTR?
According to the Microsoft documentation:
An LPCWSTR if UNICODE is defined, an LPCSTR otherwise. For more
information, see Windows Data Types for Strings.
And the LPCWSTR is:
A pointer to a constant null-terminated string of 16-bit Unicode characters. For more information, see Character Sets Used By Fonts.
First, you must check out what type of encoding are using your program; it seems that you're using UNICODE, so in the end you're trying to convert a const pointer to chars (the "OFF" constant) to a const pointer to wchar_t, and (logically) the conversion isn't allowed.
Then, you can choose the correct string type; if UNICODE is defined, your #define must be wide string:
// Note the L
#define METHOD_ONE L"OFF"
You can also define it this way:
#ifdef UNICODE
#define METHOD_ONE L"OFF"
#else
#define METHOD_ONE "OFF"
#endif
Or use the _T macro suggested by Roman R. The only that this macro does is to append L prefix to the text:
#ifdef UNICODE
#define _T(x) L ##x
#else
#define _T(x) x
#endif
In the end, you must be aware of what kind of string are using; but Microsoft is hidding it by using an obscure chain of #defines and typedefs.