Using __LINE__ in a macro definition [duplicate] - c++

This question already has answers here:
Creating C macro with ## and __LINE__ (token concatenation with positioning macro)
(3 answers)
Closed 7 years ago.
In a macro I want to generate a variable with a different name and try to use __LINE__ as a way to differentiate them. A simplified sample:
#define UNIQUE_INT int prefix##__LINE__
UNIQUE_INT;
UNIQUE_INT;
But it seems that __LINE__ is not expanding as I get "int prefix__LINE__' : redefinition" in the second one.
I suppose that __LINE__ can not be used in a macro definition as if it expanded would do to the line number of the #definition rather than the line of the invocation of the macro, but let me ask just in case someone has something to say.

The problem is that in the preprocessor, the ## takes place before __LINE__ is expanded. If you add another layer of indirection, you can get the desired result.
For technical reasons you actually need two macros (sometimes if you use this in an existing macro you don't need the second one, it seems...):
#define TOKEN_PASTE(x, y) x##y
#define CAT(x,y) TOKEN_PASTE(x,y)
#define UNIQUE_INT \
int CAT(prefix, __LINE__)
UNIQUE_INT;
UNIQUE_INT;

Related

How to implement C/C++ variadic logging macro with __FILE__ and __LINE__ info for multiple platforms? [duplicate]

This question already has answers here:
Standard alternative to GCC's ##__VA_ARGS__ trick?
(12 answers)
#define macro for debug printing in C?
(14 answers)
Closed 3 years ago.
I want to implement a C/C++ variadic logging macro, which contains __FILE__ and __LINE__ information.
This is my simple implementation:
#include <stdio.h>
#define MYLOG(format, ...) printf("%s:%d " format, __VA_ARGS__)
The only issue is that, this macro doesn't compile when my logging has no parameters, for example:
MYLOG("hello world");
I've read some wikis and blogs, there's a solution for GCC compiler:
#include <stdio.h>
#define MYLOG(format, ...) printf("%s:%d " format, ##__VA_ARGS__)
But is there a more standard way to implement this macro working on GCC/Clang/MSVC compilers?
If your compiler supports C++20 then there is a standard way to solve this problem using __VA_OPT__. __VA_OPT__(,) will expand to a comma if __VA_ARGS__ is not empty. So when __VA_ARGS__ is empty, there's no extra comma and no compilation error.
#define MYLOG(format, ...) printf("%s:%d " format __VA_OPT__(,) __VA_ARGS__)

In C++ can one use a macro to define a macro using an argument as the macro name? [duplicate]

This question already has answers here:
Escaping a # symbol in a #define macro?
(8 answers)
Closed 5 years ago.
I want to use a macro to define another macro in C++. Were the macro to define the macro has two arguments, one the name of a macro to do an "#ifdef" test on, the other the name of the new macro to #define. This example is pared down. The real situation is complicated which is why I want to factor it out.
#define TEST_ME // or NOT
#define DEFINE_A_MACRO( _test_me_, _define_me_ ) \
\
#ifdef (actual value of)_test_me_ \
#define (actual value of _define_me_) One Thing \
#else \
#define (actual value of _define_me_) Another Thing \
#endif
...
DEFINE_A_MACRO( TEST_ME, DEFINE_ME )
Is there any way to do this ?
I doubt it but might as well pose the question :)
No. while the preprocessor can support multiple levels of token replacement (one macro may reference another), this only applies to tokens. You can't generate new preprocessor directives.
In other words, you solve this by
#ifdef TEST_ME
#define THING ONETHING
#else
#define THING ANOTHERTHING
#endif
#define DEFINE_ME THING
(Or by writing C++ code - macro's are really unnecessary these days)

Removing extra parentheses from C++ macro

I have a bunch of source code that uses double-parentheses for a bunch of macro calls where the 2nd arg and forward is a varargs for a print statement.
DEBUG((1,"here is a debug"))
DEBUG((1,"here is %d and %d",42,43))
etc..
I want to write a macro that can print args 2-..., but I can't figure out how to remove the extra parentheses so I can access the args.
I.e., this obviously does not work:
#define DEBUG(ignore,...) fprintf(stderr,__VA_ARGS__)
And the following attempt to be sneaky also fails (with 'DEBUG2 not defined'):
#define DEBUG2(ignore,...) fprintf(stderr,__VA_ARGS__)
#define DEBUG(...) DEBUG2
Without editing all the macro calls to remove parens, how can I define a macro that will do this?
You may do:
#define PRINTF(unused, ...) fprintf(stderr, __VA_ARGS__)
#define DEBUG(arg) PRINTF arg

Function-like macros without body but different names of argument

The following code:
#define MYDEF(x)
#define MYDEF(y)
int main() {}
gives me an error (or warning if pedantic-errors is disabled):
'MYDEF' macro redefined
The reason is different names for unused argument (more over, there is no body in macro). But why? In which situations it can be a problem?
Because macros are not functions. They are textual replacements done by the preprocessor and can't be overloaded.
It is (almost) similar to find and replace in your editor. Find all the occurences of MYDEF and replace it with (empty string in your case). It's more complicated, of course, but the idea is the same.
And you can't overload this find and replace, can you? :)
The macro can be redefined, and the macro is uniquely determined by the macro name. For example, code like this :
#define MYDEF(x) //the name of the macro is 'MYDEF'
#define MYDEF(x, y) //the name of the macro is 'MYDEF' too
MYDEF(x) will be redifined(or covered) by MYDEF(x, y), you can't write code MYDEF(x) any more after defining MYDEF(x, y)
so, if you write code :
#define MYDEF(x)
#define MYDEF(y) //(There compiler will give warning). You can write
//`#undef MYDEF` before `#define MYDEF(y)` to avoid it.
MYDEF(x) will be redifined by MYDEF(y).

Creating macro using __LINE__ for different variable names [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Creating C macro with ## and LINE (token concatenation with positioning macro)
I am trying to use the __LINE__ macro to generate different variable names. I have a scoped benchmark class called Benchmark(located in the utils namespace) and it's constructor takes a string. Here is the macro definition I have created:
#define BENCHMARK_SCOPE utils::Benchmark bm##__LINE__(std::string(__FUNCTION__))
Unfortunately this causes the following error:
<some_file_name>(59): error C2374: 'bm__LINE__' : redefinition; multiple initialization
This leads me to the conclusion the __LINE__ macros does not get expanded. I have created my macross according to this post. Do you have ideas why __LINE__ does not get expanded?
EDIT: probably the compiler info is also relevent. I am using visual studio 2010.
You need to use combination of 2 macros:
#define COMBINE1(X,Y) X##Y // helper macro
#define COMBINE(X,Y) COMBINE1(X,Y)
And then use it as,
COMBINE(x,__LINE__);
You're using token pasting. This occurs before the recursive macro
expansion (so that you can token paste to get the name of a macro you
want to invoke). Thus:
#define PASTE(a,b) a ## b
will paste the exact arguments passed to PASTE, then try to expand
the resulting new token. To get the effect you want, you need an
additional level of indirection:
#define PASTE_HELPER(a,b) a ## b
#define PASTE(a,b) PASTE_HELPER(a,b)
Here, the arguments to PASTE will be expanded before PASTE_HELPER is
invoked.
try this code, I've used it in an older project
#define CONCATENATE_DIRECT(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
#ifdef _MSC_VER // Necessary for edit & continue in MS Visual C++.
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __COUNTER__)
#else
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#endif
int ANONYMOUS_VARIABLE(var)
EDIT:
I think you should use COUNTER in visual studio only if also using precompiled headers.