I would like to make a macro-like object that can detect its use in the current scope and behave differently in such a case. For example, consider the following fragment of code
#define FOO /* expand to printf("first time\n"); or printf("not a first time\n"); */
{
FOO // prints "first time"
FOO // prints "not a first time"
{
FOO // prints "first time"
FOO // prints "not a first time"
}
FOO // prints "not a first time"
}
Is it possible to make this with macro or any other language element in C++?
For people curious why I need this: I would like to make an easily copy-pastable macro FOO that I can put everywhere to get time spent in code fragment between two occurrences of it.
For example:
FOO // initialize timer
// code fragment 1
FOO // print the time spent in code fragment 1
// code fragment 2
FOO // print the time spent in code fragment 2
// code fragment 3
FOO // print the time spent in code fragment 3
You can create a scoped timer class:
#include <chrono>
#include <iostream>
#include <thread>
class ScopedTimer {
using clock = std::chrono::steady_clock;
std::chrono::time_point<clock> _begin;
public:
ScopedTimer() : _begin{ clock::now() }
{}
ScopedTimer(ScopedTimer const&) = delete;
ScopedTimer& operator=(ScopedTimer const&) = delete;
void print_duration() {
using namespace std::chrono;
auto const duration = duration_cast<milliseconds>(clock::now() - _begin);
std::cout << "Duration: " << duration.count() << '\n';
}
};
int main() {
ScopedTimer timer{};
std::this_thread::sleep_for(std::chrono::seconds(1));
timer.print_duration();
std::this_thread::sleep_for(std::chrono::seconds(1));
timer.print_duration();
}
How about this one?
#define FOO(block) /* The code section to time */ \
do{ \
/* code for start of timing */ \
{ block } \
/* code for end of timing */ \
while(0); \
C Preprocessor macros are often discouraged. Although in your case, you are using them to reduce the repetition of printf("first time\n"); and reducing repetition in code is a good thing. Assuming that we only want to consider macro-based solutions, this is what I would do:
#define FOO_FIRST printf("first time\n");
#define FOO_ADDITIONAL printf("not a first time\n");
{
FOO_FIRST // prints "first time"
FOO_ADDITIONAL // prints "not a first time"
{
FOO_FIRST // prints "first time"
FOO_ADDITIONAL // prints "not a first time"
}
FOO_ADDITIONAL // prints "not a first time"
}
Your originally-posted solution was trying to use a single FOO for both FOO_FIRST and FOO_ADDITIONAL, as a "convenience" to the macro-user. My suggestion is to resist the urge to crease such a "convenience", because what it really does is hide the fact that it is doing something different depending on which expansion it is. Don't hide that fact from the macro-user -- in my opinion, it's not a good thing to have the macro-user using a macro "without thinking". Instead, programmers should be thinking about the effects of the code that they write, and the resultant code is more readable when the usage of two separate macro names makes it clear that the programmer is doing two separate actions.
Using macros to reduce repetition is justifiable; using macros to obscure the programmer's intent is something I wouldn't do.
In your reply to one of the other potential solutions, you indicated that you wanted a macro to have an effect something like a context-sensitive function that was named Initialize_Or_Print(). This fact is an indication that you are going down the wrong road. Programming constructs should have single, clear purposes. Whenever you start to get the feeling that you are needing to cram too many separate purposes into one construct (Initialize_Or_Print_Or_SpawnNewPlayer_Or_BoilWater() is the direction you're headed), it's probably a bad thing and should be factored into separate pieces.
#define FOO { if(!foo_check) std::cout << "first time" << std::endl; else std::cout << "not a first time" << std::endl; foo_check=!foo_check; };
pretty obvious, i'd say, with the caveat to define
bool foo_check=false;
at the right level, for example at the start of the function, at start of main or as global variable for a file scope.
Said so, I use a timer class as per #Ayxan Haqverdili answer.
You can make a macro that modifies each time. (at least in gcc and I believe in msvc too):
// (only tried in gcc)
#define FLIPFLOP (__COUNTER__ % 2)
#define FOO std::cout <<(!FLIPFLOP ? "flip\n":"flop\n");
#include <iostream>
int main()
{
FOO
FOO
FOO
FOO
}
but you can't by nature make the preprocessor depend on source code block scope, since what { or } actually means is only determined later by the parser. The preprocessor knows nothing about it.
There are various proposals for "compiletime programming" for example http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2320r0.pdf, but whether they will address this type of use, I don't really know
Building on ...an answer that was deleted while I was typing this. You can get the timer behavior you want via RAII and macro expansion:
BuildConfig.hpp
//...
#ifdef _DEBUG
# undef PROFILE_BUILD
#else
# define PROFILE_BUILD
#endif
#define TOKEN_PASTE_SIMPLE(x, y) x##y
#define TOKEN_PASTE(x, y) TOKEN_PASTE_SIMPLE(x, y)
#define TOKEN_STRINGIZE_SIMPLE(x) #x
#define TOKEN_STRINGIZE(x) TOKEN_STRINGIZE_SIMPLE(x)
//...
ProfileLogScope.hpp
#pragma once
#include <chrono>
#include <string>
class ProfileLogScope {
public:
explicit ProfileLogScope(const char* scopeName) noexcept;
~ProfileLogScope() noexcept;
ProfileLogScope() = delete;
ProfileLogScope(const ProfileLogScope&) = delete;
ProfileLogScope(ProfileLogScope&&) = delete;
ProfileLogScope& operator=(const ProfileLogScope&) = delete;
ProfileLogScope& operator=(ProfileLogScope&&) = delete;
protected:
private:
using time_point_t = std::chrono::time_point<std::chrono::steady_clock>;
const char* _scope_name = nullptr;
time_point_t _time_at_creation{};
};
#if defined PROFILE_LOG_SCOPE || defined PROFILE_LOG_SCOPE_FUNCTION
#undef PROFILE_LOG_SCOPE
#undef PROFILE_LOG_SCOPE_FUNCTION
#endif
#ifdef PROFILE_BUILD
#define PROFILE_LOG_SCOPE(tag_str) ProfileLogScope TOKEN_PASTE(plscope_, __LINE__)(tag_str)
#define PROFILE_LOG_SCOPE_FUNCTION() PROFILE_LOG_SCOPE(__FUNCSIG__)
#else
#define PROFILE_LOG_SCOPE(tag_str)
#define PROFILE_LOG_SCOPE_FUNCTION()
#endif
ProfileLogScope.cpp
#include "ProfileLogScope.hpp"
#include <iostream>
#include <ostream>
#include <iomanip>
#include <sstream>
ProfileLogScope::ProfileLogScope(const char* scopeName) noexcept
: _scope_name(scopeName)
, _time_at_creation(std::chrono::steady_clock::now()) {
/* DO NOTHING */
}
ProfileLogScope::~ProfileLogScope() noexcept {
const auto now = std::chrono::steady_clock::now();
const auto elapsedTime = (now - _time_at_creation);
std::cout << "ProfileLogScope " << _scope_name << " took " << elapsedTime.count() << " nanoseconds.\n";
}
Usage
void Foo();
int main() {
PROFILE_LOG_SCOPE_FUNCTION()
{
PROFILE_LOG_SCOPE("Algorithm 1");
}
Foo();
}
void Foo() {
PROFILE_LOG_SCOPE_FUNCTION();
//...
}
The macros expand to unique-per-line variable names and are no-ops when explicitly not in a profiling mode.
When C++20's std::source_location becomes available, this will become a lot less messy. See Jason Turner's video on the topic: https://www.youtube.com/watch?v=TAS85xmNDEc
Related
#include <iostream>
#define MY_CONST 10
#define MY_OTHER_CONST MY_CONST
#undef MY_CONST
int main() {
enum my_enum : int {
MY_CONST = 100
};
std::cout << MY_OTHER_CONST;
return 0;
}
I would expect 10 as an output, but this program outputs 100. Can someone explain what is going on here?
https://godbolt.org/z/77EedG11x
#define MY_OTHER_CONST MY_CONST defines the macro MY_OTHER_CONST to have a replacement list of MY_CONST. No replacement is performed when defining a macro.
In std::cout << MY_OTHER_CONST;, MY_OTHER_CONST is replaced by its replacement list, becoming MY_CONST. At this point, there is no macro definition for MY_CONST, so no further replacement is performed. Then MY_CONST refers to the enum constant MY_CONST, which has value 100.
The 1 seems unnecessary (and possibly misleading) in the following example, but I have seen this multiple times when used for checking #ifdefs:
#ifndef __NEWLIB_H__
#define __NEWLIB_H__ 1
Is there a difference or reason for using the above versus a plain #define __NEWLIB_H__?
1 is true, so you can use the macro in an #if test. That's not usually very useful for header guards, but it certainly doesn't hurt. For other macros which might be tested in boolean expressions, the true value is definitely useful.
Some people just like the consistency. And that's the definition that gcc chooses by default if you put -D TESTME on the command line.
However,
#define __NEWLIB_H__ 1
is not cool unless it's in an implementation of the standard library, because names starting with two underscores (or an underscore and a capital letter) are reserved for use by the implementation, and should never be used in portable applications.
When used purely as an #include guard, there is no difference between
#ifndef __NEWLIB_H__
#define __NEWLIB_H__
and
#ifndef __NEWLIB_H__
#define __NEWLIB_H__ 1
However, in general, there is a distinction.
Compiler error
#ifndef ABCD
#define ABCD
#endif
int main()
{
#if defined(ABCD) && (ABCD == 1)
std::cout << "ABCD is 1\n";
#else
std::cout << "ABCD is not 1\n";
#endif
}
Outputs the string "ABCD is 1"
#ifndef ABCD
#define ABCD 1
#endif
int main()
{
#if defined(ABCD) && (ABCD == 1)
std::cout << "ABCD is 1\n";
#else
std::cout << "ABCD is not 1\n";
#endif
}
Outputs the string "ABCD is not 1"
#ifndef ABCD
#define ABCD 10
#endif
int main()
{
#if defined(ABCD) && (ABCD == 1)
std::cout << "ABCD is 1\n";
#else
std::cout << "ABCD is not 1\n";
#endif
}
#define by itself will replace the symbol with nothing.
On the other hand, #define 1, as you call it, will replace the symbol with 1 everywhere it is found in the file. So, for example, the following code:
#include <iostream>
#define EXAMPLE "hello"
int main()
{
std::cout << EXAMPLE;
return 0;
}
prints
hello
This is because EXAMPLE here is replaced with "hello", making the print statement equivalent to:
std::cout << "hello";
If we change the #define statement to this instead:
#define EXAMPLE
This will give a compile error:
main.cpp: In function βint main()β:
main.cpp:15:25: error: expected primary-expression before β;β token
std::cout << EXAMPLE;
As to why you would ever use this second form of #define, it's because there is another processor directive that you can use called #ifdef:
#include <iostream>
#define EXAMPLE
int main()
{
#ifdef EXAMPLE
std::cout << "EXAMPLE defined.";
#endif
return 0;
}
This will print:
EXAMPLE defined.
Because #ifdef (and its relative #ifndef) only require that the symbol be defined, we don't really need to give it a value. It just needs to be there to work.
A common place you see this kind of stuff is with header guards (which is probably what you're seeing). You can also see it with platform identification, or even to determine whether the compiler is using C++ or not.
I'm trying to create a macro for debug logging purposes. Here is an extra simplified version:
#if defined _DEBUG
#define LOG std::cout
#else
#define LOG IGNORETHISLINEOFCODE
#endif
/* ... */
LOG << "Here's some debug code";
I've been thinking of the ways I can tell the compiler to ignore this line of code that starts with "LOG". I'm personally not looking for alternative ways, such as #define LOG( ... ) (void)0. Here's what I've tried:
Overloading the leftshift operator for void as an inline constexpr that does nothing (which still results in it being visible in the disassembly; I don't want that)
Defining LOG as: #define LOG //, but the comment identifier isn't substituted in
Any ideas? Like I said earlier, I don't want any alternatives, such as surrounding all the log code with #if defined _DEBUG
If your version of C++ handles if constexpr I've come to like things along this line for what you're asking.
#include <iostream>
template <bool Log>
struct LOGGER {
template <typename T>
LOGGER& operator<<(T const &t) {
if constexpr (Log)
std::cout << t;
return *this;
}
};
LOGGER<false> LOG;
int main (int argc, char const* argv[])
{
LOG << "A log statement." << '\n';
return 0;
}
Your question and constraint ("I don't want any alternatives") are weirdly specific.
I've been thinking of the ways I can tell the compiler to ignore this line of code that starts with "LOG"
Don't do that, it'll be trivially broken by a multi-line logging statement. Any code that can suddenly break due to otherwise-legal reformatting is best avoided.
Next we have
... which still results in it being visible in the disassembly ...
which shouldn't be true if the code is genuinely dead, you have a decent compiler, and you turn on optimization. It's still some work, though.
The usual solution is something like
#ifdef NDEBUG
#define LOG(EXPR)
#else
#define LOG(EXPR) std::cerr << EXPR
#endif
This is an alternative, but it's not an alternative such as surrounding all the log code with #if defined, so I don't know if it's a problem for you or not.
It does have the advantage of genuinely compiling to nothing at any optimization level.
another possibility based on the compiler optimization abilities:
#define LOG if (DEBUG) std::cout
now you can use
#define DEBUG false
LOG << "hello " << " world 1" << endl;
you should be able to use const bool DEBUG = false as well.
#if defined _DEBUG
#define LOG std::cout
#else
#define LOG /##/
#endif
This works as well. It's the answer to the original question, so I'll mark it as such, but just know that this does not support multiline operations.
I suppose you could do something like the following for multiline operations. I don't know how well it'd work.
#if defined _DEBUG
#define LOG( in ) std::cout << in
#else
#define LOG( in ) /##/
#endif
Better logic would be to define tracer policy, where you can set the logging level at the start of the application and then use the tracing level to make the decision to either log the degug information. Tracing level can be defined as an enum like
enum Tracelevel{CRITICAL, ERROR, INFO, TEST, DEBUG};
setTraceLevel(TraceLevel trcLvl){
_traceLevel = trcLvl;
};
#if defined _DEBUG
if(_traceLevel == DEBUG) {\
#define LOG std::cout
}
#endif
A lightweight logger can be found http://www.drdobbs.com/cpp/a-lightweight-logger-for-c/240147505?pgno=1
I am currently working on a feature that raised a peculiarly difficult problem.
I have two macros :
#define FOO(A) do { /*...*/ } while(0)
#define FOO_END(A) do { /*...*/ } while(0)
What FOO actually does is that it tests values (in a very peculiar way), and FOO_END prints all the test results to the standard output. The detailed content is not publicated here because it's non-modifiable.
Each one of them have several inputs (not just "A"), but I limited it to one for simplicity.
These two macros are made to be used as this: several FOO macros are to be called in succession, then the FOO_END macro needs to be called at the end. I need to ensure that no "functionnal" code is called between the first and the last test (so the values all are coherent).
Example :
int main()
{
// stuff...
FOO(1);
FOO(2);
FOO_END(3);
// stuff...
FOO(4);
FOO_END(5);
// stuff...
return 0;
}
Thus, the following code must fail to compile :
int main()
{
FOO(1);
bar(); // a random function
FOO(2);
FOO_END(3);
return 0;
}
How can I redefine my macros in order to have this feature?
Constraints
The error must be seen at compile time. I already have a version that raises an error at runtime, but it's not enough for me.
FOO and FOO_END must be macros. It's because I need to use
__LINE__ and __FILE__ within them.
C++11 is OK but I would prefer a C++03 solution. If it's possible of course.
No external libraries, if possible. I have very low flexibility on the project I need it for. However, if no native solution is possible, I am still curious.
If you use a start macro you can start an unfinished sentence in it
#define FOO_START uselessFOOFunction(
#define FOO ); do { /*...*/ } while(0); uselessFOOFunction(
#define FOO_END ); do { /*...*/ } while(0)
static void uselessFOOFunction(){}
So this will work :
int main()
{
// stuff...
FOO_START
FOO
FOO
FOO_END;
// stuff...
FOO_START
FOO
FOO_END;
// stuff...
return 0;
}
And this will fail to compile :
int main()
{
FOO_START
FOO
bar(); // a random function
FOO
FOO_END;
return 0;
}
If you also add a FOO_START macro at the start, you could generate a code which will fail to compile with various errors for incorrect examples.
The downside is that the error message won't be about the use of the foo - it will be about the incorrect language constructs the macro expansions generate. You also won't be able to use local variables.
Because of this, I would say that in this form it is unusable, but maybe you could modify it to your use case - this is similar to how some unit test frameworks are implemented.
Here's a simple example:
#include <iostream>
#define CONCAT(A,B) A ## B
#define ST_NAME(N) CONCAT(ST_, N)
#define NP_NAME(N) CONCAT(NP_, N)
#define np_NAME(N) CONCAT(np_, N)
#define MEM_NAME(N) CONCAT(mem_, N);
// NPs are helper structs that ensure that no data members are declared outside the FOO macros
#define NP_START struct NP_NAME(__LINE__) { int i;
#define NP_END } np_NAME(__LINE__); static_assert(sizeof(np_NAME(__LINE__)) == sizeof(int));
#define FOO_START struct { NP_START
#define FOO NP_END struct ST_NAME(__LINE__) { ST_NAME(__LINE__)() { std::cout << "hack!" << std::endl; } } MEM_NAME(__LINE__); NP_START
#define FOO_END NP_END } MEM_NAME(__LINE__);
void bar();
int main() {
int i;
FOO_START;
FOO;
i = 5; // error
int j = bar(); // error
FOO;
bar(); // error
FOO_END;
return 0;
}
With this, you generate an anonymous local struct, and the code will be executed by its constructor.
Edit: fixed the issue mentioned by a comment. Static_assert requires C++11, or boost for 03.
You can't do it using the macros you've proposed. There's no way to ensure no code exists between your macro statements. You can change your approach, though.
Create a macro, DO_FOO, that takes a number N which is the number of times to do FOO. The DO_FOO automatically expands to FOO N times and a single FOO_END. Example:
#define DO_FOO_IMPL_1 FOO; FOO_END
#define DO_FOO_IMPL_2 FOO; DO_FOO_IMPL_1;
#define DO_FOO_IMPL_3 FOO; DO_FOO_IMPL_2;
#define DO_FOO_IMPL_4 FOO; DO_FOO_IMPL_3;
// ... and so on, up to some maximum number N
#define DO_FOO(N) DO_FOO_IMPL_ ## N
Then you use it like this:
int main()
{
// stuff...
DO_FOO(2);
// stuff...
DO_FOO(1);
// stuff...
return 0;
}
My approach would be this: if you don't want people calling arbitrary code between calls to FOO and FOO_END, then put all the FOO calls into a single FOO_LIST call which calls all of them and then calls FOO_END implicitly. That way the rule is enforced by the macro syntax itself.
i.e. instead of:
FOO(1);
FOO(2);
FOO(3);
FOO_END;
have your program do this:
FOO_LIST(1, 2, 3);
... which will be expanded by the preprocessor to into FOO(1); FOO(2); FOO(3); FOO_END();
Here's an example implementation that supports up to 5 arguments in a FOO_LIST; it can be extended if you need more.
#include <stdio.h>
#define FOO(x) do {printf("foo(%i)!\n", x);} while(0)
#define FOO_END do {printf("foo_end!\n\n");} while(0)
// Support up to 5 FOO calls in a FOO_LIST, for now (can be extended as necessary)
#define FOO_LIST_1(f1) {FOO(f1); FOO_END;}
#define FOO_LIST_2(f1, f2) {FOO(f1); FOO(f2); FOO_END;}
#define FOO_LIST_3(f1, f2, f3) {FOO(f1); FOO(f2); FOO(f3); FOO_END;}
#define FOO_LIST_4(f1, f2, f3, f4) {FOO(f1); FOO(f2); FOO(f3); FOO(f4); FOO_END;}
#define FOO_LIST_5(f1, f2, f3, f4, f5) {FOO(f1); FOO(f2); FOO(f3); FOO(f4); FOO(f5); FOO_END;}
#define GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
#define FOO_LIST(...) GET_MACRO(__VA_ARGS__, FOO_LIST_5, FOO_LIST_4, FOO_LIST_3, FOO_LIST_2, FOO_LIST_1)(__VA_ARGS__)
int main(int,char **)
{
printf("Some functional code here...\n");
FOO_LIST(1);
printf("Some more functional code here...\n");
FOO_LIST(1, 2);
printf("Some more functional code here...\n");
FOO_LIST(1, 2, 3);
return 0;
}
I need a macro to expand to a c++ comment, is that possible?
I've got this:
#define SLASH(x,y) x y
#define OUT SLASH(/,/)
int main(int argc, char *argv[])
{
OUT << "text";
return 0;
}
And need to expand to this:
{
// << "text";
return 0;
}
I've also tried this:
#define SLASH(x) /x
#define OUT SLASH(/)
But the result is still the same:
int main(int argc, char *argv[])
{
/ / << "text";
return 0;
}
No it's not possible because in C++ comments are removed before macros are expanded.
(See 2.1 of the standard, comment removal happens in phase 3, macro expansion in phase 4.)
What about replacing it with a function object that does nothing instead?
static class NullOutput {
public:
template <typename T>
const NullOutput &operator<<(T arg) const {
return *this;
}
} NullOutputObj;
#define OUT NullOutputObj
The net result is that the object is removed from the code and replaced by inlined template expansions, that are then optimized out as they do nothing. Result is absolutely no code overhead.
As others mentioned there is no guaranteed way to define the kind of macro you are looking for. Other ways to achieve results that are similar to what you seem to be trying to achieve are wrapping your output statement in a conditional block or define a custom output stream that just discarded all output. The two approaches may even be combined so that behaviour could be switched by changing a single macro definition.
Comments are removed from the source code before the preprocessor runs. So you cannot do this.
an alternate to what you want to achieve would be this :
http://donjaffer.blogspot.in/2012/09/dprintf-debug-macro-in-c.html
#define DEBUG // comment if you do not want the debug statments to appear.
#ifdef DEBUG
#define DPRINTF(fmt, ...) \
do { printf("my_file: " fmt, ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) \
do { } while (0)
#endif
wherever you are trying to print the statements, instead of COUT << you can use
DPRINTF("Your text here\n");