Using macro with string fails on VC 2015 - c++

Why does this fail to compile?
char programDate[] = "("__DATE__")";
But this compiles fine (see space):
char programDate[] = "(" __DATE__")";
I do know VC2015 now supports literal-operators. But shouldn't that be in compilation phase? __DATE__ should have been processed by the pre-processor. What is going on here?
I thought of some mix-match issue with Unicode/non-Unicode build - but it doesn't help. It's not just issue with pre-defined macros, but with user defined also:
#define MACRO "abc"
char data[] = "("MACRO")";
EDIT:
Error C3688 invalid literal suffix '__DATE__'; literal operator or literal operator template 'operator ""__DATE__' not found

Since C++11, user-defined literals exist and are part of preprocessing. The grammar is:
preprocessing-token:
user-defined-string-literal
// other stuff...
user-defined-string-literal:
string_literal ud-suffix
ud-suffix:
identifier
So "("__DATE__ matches preprocessing-token, but "(" __DATE__ doesn't (that is two separate preprocessing tokens).
Macro replacement happens after tokenization. Since there is no token __DATE__ in your first example, there is no replacement.

Related

How to make GCC reduce 'arg,##__VA_ARGS__' to 'arg' to use it as single macro argument?

I have these macros defined for visual studio and clang and they both compile fine
#if defined(_MSC_VER)
# define _declare_func(...) PP_CAT(PP_CAT(_declare_func_, PP_NARG(__VA_ARGS__)),(__VA_ARGS__))
# define declare_func(...) _declare_func PP_LEFT_PAREN notused,##__VA_ARGS__ PP_RIGHT_PAREN
#else // clang version
# define _declare_func(...) PP_CAT(_declare_func_, PP_NARG(__VA_ARGS__))(__VA_ARGS__)
# define declare_func(...) _declare_func ( notused,##__VA_ARGS__ )
#endif
#define _declare_func_1(notused) void my_function()
#define _declare_func_2(notused, scope) void scope::my_function()
class MyClass
{
declare_func();
};
declare_func(MyClass) { }
PP_CAT is a classic multilevel concat macro
PP_NARG counts the number of macro arguments
PP_LEFT_PAREN and PP_RIGHT_PAREN reduce to '(' and ')'
Is there any way to achieve this with GCC ? ( I tried both macro version with GCC 5.2, both fail to compile because the comma seem to be propagated during macro resolution and removed only at the end of preprocessing, making PP_NARG always reduce to '2' and never '1')
Thanks !
From doc:
Second, the ‘##’ token paste operator has a special meaning when placed between a comma and a variable argument. If you write
#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
and the variable argument is left out when the eprintf macro is used, then the comma before the ‘##’ will be deleted. This does not happen if you pass an empty argument, nor does it happen if the token preceding ‘##’ is anything other than a comma.
eprintf ("success!\n")
==> fprintf(stderr, "success!\n");
The above explanation is ambiguous about the case where the only macro parameter is a variable arguments parameter, as it is meaningless to try to distinguish whether no argument at all is an empty argument or a missing argument. In this case the C99 standard is clear that the comma must remain, however the existing GCC extension used to swallow the comma. So CPP retains the comma when conforming to a specific C standard, and drops it otherwise.
So for
#define declare_func(...) _declare_func ( notused,##__VA_ARGS__ )
the comma remain in C standard, you may use -std=gnu99 or -std=gnu++11 to drop the comma and have your working macro.
Demo
To make your macro works with -std=c++11, you have so to force to have at least one argument.

Dereferencing strings in preprocessor expressions

My reading of the draft standard documents suggests that it should be legal to dereference a string literal, either with a unary * or with a constant subscript, in a preprocessor expression. For instance, I should be able to say (using the predefined __ DATE __ macro which expands to a quoted string):
#if *__DATE__ == 'A'
or
#if __DATE__[0] == 'A'
If I do this in GCC, with -std=gnu++0x, the former complains
error: operator '*' has no left operand
and the latter complains
error: token ""Feb 16 2016"" is not valid in preprocessor expressions
The standards don't seem to define constant-expression any differently between the compiler and the preprocessor. The compiler happily compiles stuff like:
int foo[*__DATE__];
or
int foo[__DATE__[0]];
at global scope, proving that these are legitimate constant expressions.
I call foul. It seems to me that the standard requires the preprocessor to handle these types of expressions in #if or #elif clauses. Does anyone have any counterargument, before I go and report this as a GCC bug?
Your technique works in code, like an if (*_ _ DATE _ _ == 'A') statement, but not in an #IF macro. The preprocessor won't do that sort of expression evaluation.

Is it possible to define another preprocessor directive?

I've been looking through code golf and got an idea to try this code:
#define D #define after adding this line, everything worked fine, however I expanded it into this:
#define D #define
D VALUE
And here I got 5 compilation error. If I change D into #define everything is fine, can someone explain, why this code is illegal?
NOTE: I used VS2008 compiler.
EDIT: After some answers I see that I needed to give compilations error list:
error C2121: '#' : invalid character : possibly the result of a macro expansion
error C2146: syntax error : missing ';' before identifier 'VALUE'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2144: syntax error : 'void' should be preceded by ';'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
First error shows that D is not just define but also includes #.
C 2011 (N1570) 6.10.3.4 3: “The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one,…”
C++ 2010 (N3092) 16.3.4 [cpp.rescan] 3 has exactly the same text.
This code is illegal because language specification says it is illegal. According to C and C++ preprocessor specification, whatever code you build using preprocessor will never be interpreted as another preprocessor directive. In short, you cannot build preprocessor directives using preprocessor. Period.
(Also, you cannot build comments using preprocessor.)
It does look like your preprocessor is making the substitution you want, but you likely wouldn't get the behaviour you want - the preprocessor is normally just a single pass operation. Example (with clang, but you should be able to reproduce by using the appropriate VS2008 flags):
$ cat example.c
#define D #define
D VALUE
$ cc -P -E example.c
#define VALUE
That #define VALUE is going straight through to the compiler, which won't know what to do with it - it's a preprocessor directive, after all. Clang's error, for reference, is similar to yours:
$ cc -c example.c
example.c:2:1: error: expected identifier or '('
D VALUE
^
example.c:1:11: note: expanded from macro 'D'
#define D #define
^
1 error generated.
That won't work because preprocessing is performed in a single pass. For example, consider the next code :
#define MYDEFINEWEIRD #define
MYDEFINEWEIRD N 6
int main() {
return 0;
}
After preprocessing, your code will looks like :
#define N 6
int main() {
return 0;
}
and "#define" is not a valid syntax on C or C++. Also, since the resulting preprocessor directive is not going to be processed, it won't resolve subsequent references to the "N" macro in your code.
Just for fun, you can call the preprocesor twice from the command line using g++/gcc. Consider the next code (define.cpp) :
#include <iostream>
#define MYDEFINEWEIRD #define
MYDEFINEWEIRD N 6
using namespace std;
int main() {
cout << N << endl;
return 0;
}
Then you can do:
$ g++ -E define.cpp | g++ -o define -x c++ - && ./define
and will output:
6
Lines of code in the pre-processors eyes are either pre-processor statements (And thus don't have any replacements done on them) or normal text statements (And have replacements done). You can't have one be both, so once you have 'D' be replaced it's only going to look to see if there are any more macros to replace. Since there are none, it just leaves '#define' in the C++ code as it is and then the C++ compiler will error when it sees it (Since '#define' isn't valid C++ code).
So show my point more, this is invalid code for the pre-processor:
#define D define
#D value
Because the pre-processor doesn't do any macro replacement on pre-processor statements, and "#D" isn't a recognized pre-processor command. And this:
#define D #define
D value
Results in this C++ code:
#define value
Which is invalid because the pre-processor is already done being run.
Looking at the grammar in 16 [cpp] paragraph 1, a replacement-list consists of pp-tokens which may include the production # no-directive which is described in paragraph 2 of the same paragraph as
A non-directive shall not begin with any of the directive names appearing in the list.
That is, something of the form
#define NAME # define
happens to be illegal! Also note that the # in this context does not turn the next word into a string: the quoting following a # only happens shen the # is immediately followed by a macro parameter name in a function-style macro.

Argument Preceded by a # Token in a Macro

#define LINK_ENTITY_TO_CLASS(mapClassName,DLLClassName) \
static CEntityFactory<DLLClassName> mapClassName( #mapClassName );
This is a macro from the Alien Swarm mod for Half-Life 2, meant to be compiled with MSVC.
I've never seen an argument preceded by a # in a macro before, and I'm not sure if this is a MSVC specific thing or just uncommon. What does it mean?
This is part of both standard C and C++ and is not implementation-specific. The # preprocessing operator stringizes its argument. It takes whatever tokens were passed into the macro for the parameter designated by its operand (in this case, the parameter mapClassName) and makes a string literal out of them. So, for a simple example,
#define STRINGIZE(x) # x
STRINGIZE(Hello World)
// gets replaced with
"Hello World"
Note that the argument tokens are not macro replaced before they are stringized, so if Hello or World were defined as a macro, the result would still be the same. You need to use an extra level of indirection to get the arguments macro replaced (that linked answer discusses the concatenation operator, ##, but applies equally to the stringization operator.

What is the purpose of the ## operator in C++, and what is it called?

I was looking through the DXUTCore project that comes with the DirectX March 2009 SDK, and noticed that instead of making normal accessor methods, they used macros to create the generic accessors, similar to the following:
#define GET_ACCESSOR( x, y ) inline x Get##y() { DXUTLock l; return m_state.m_##y;};
...
GET_ACCESSOR( WCHAR*, WindowTitle );
It seems that the ## operator just inserts the text from the second argument into the macro to create a function operating on a variable using that text. Is this something that is standard in C++ (i.e. not Microsoft specific)? Is its use considered good practice? And, what is that operator called?
Token-pasting operator, used by the pre-processor to join two tokens into a single token.
This is also standard C++, contrary to what Raldolpho stated.
Here is the relevant information:
16.3.3 The ## operator [cpp.concat]
1 A ## preprocessing token shall not
occur at the beginning or at the end
of a replacement list for either form
of macro definition.
2 If, in the
replacement list, a parameter is
immediately preceded or followed by a
## preprocessing token, the parameter is replaced by the corresponding
argument’s preprocessing token
sequence.
3 For both object-like and
function-like macro invocations,
before the replacement list is
reexamined for more macro names to
replace, each instance of a ##
preprocessing token in the replacement
list (not from an argument) is deleted
and the preceding preprocessing token
is concatenated with the following
preprocessing token. If the result is
not a valid preprocessing token, the
behavior is undefined. The resulting
token is available for further macro
replacement. The order of evaluation
of ## operators is unspecified.
It's a preprocessing operator that concatenates left and right operands (without inserting whitespace). I don't think it's Microsoft specific.
This isn't Standard C++, it's Standard C. Check out this Wikipedia article.
And is it a good practice? In general, I hate pre-processor macros and think they're as bad as (if not worse than) Goto.
Edit: Apparently I'm being misunderstood by what I meant by "This isn't Standard C++, it's Standard C". Many people are reading the first phrase and failing to read the second. My intent is to point out that macros were inherited by C++ from C.
As Mehrdad said, it concatenates the operands, like:
#define MyMacro(A,B) A ## B
MyMacro(XYZ, 123) // Equivalent to XYZ123
Note that MISRA C suggests that this operand (and the # 'stringify' operand) should not be used due to the compiler dependent order of calculation.
It is token pasting operator allowed by Standard C++ (see 16.3.3 for details).
As for good practice: using macro is not a good practice IMHO (in C++).
it's the concatenation for macro arguments i.e.
GET_ACCESSOR (int, Age);
will be expended to
inline int GetAge() { DXUTLock l; return m_state.m_Age;};