Typically, when I erase an element from a set, I want to assert that it was actually erased:
ie
assert(s.erase(e));
but then the element doesn't get erased when NDEBUG is set. But if I write
bool removed = s.erase(e);
assert(removed);
the compiler complains that 'removed' is unused when NDEBUG is set.
How can I do this right?
I ended up just creating a utility method:
inline void run_and_assert(bool b) {
assert(b);
}
now I can say
run_and_assert(s.erase(e));
Are there any drawbacks to this? It seems simpler to me than luiscubal's solution
The first example is wrong because the assert expression will be removed when NDEBUG is defined, so s.erase(e) won't be called at all.
The argument of assert should NEVER have side-effects.
The second approach is better, though the warning might indeed be annoying, but there are ways to silence the warning.
Alternatively you could come up with your own assert statement that always executes the code.
#ifdef NDEBUG
#define assert_always_execute(x) (x)
#else
#define assert_always_execute(x) assert(x)
#endif
I wrote my own like luiscubal's suggestion except instead of ugly #define's I made a short inline method:
inline void assert_always_execute(bool x) {
assert(x);
}
Related
Background: My code, which I cannot post here will eventually run on a microcontroller, and the macros just offer a way to create multiple pin definition functions, via 1 single macro define mechanic. I use windows and gcc to experiment around with those.
I tried to abstract the problem as much as possible. I use the std console functions cause it is convenient for me to display it in the console window. As such, I also save the file as .cpp and compile it with g++ on windows.
Say I set up my code like this:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x) MACRO2(_x)
#define BAR 3
void fooBAR(int num)
{
std::cout << num << std::endl;
}
If I run the following code (working example)
int main()
{
MACRO2(BAR);
return 0;
}
first BAR gets inserted into ##_x and thus defines the function name which is to be called and then BAR gets inserted as the argument of that function and gets expanded to its value, so we get fooBAR(3). The code works, there are no errors.
Now if I try to add a macro in between (and this is the real world situation I am faced with for reasons I cannot go into), my code looks like this:
int main()
{
MACRO1(BAR);
return 0;
}
But this code throws an error, because when MACRO1(BAR) gets substituted with MACRO2(BAR), (BAR) then gets expanded into 3, and MACRO2(3) leads to foo3(3) which isn't defined, as confirmed by the error log:
error: 'foo3' was not declared in this scope
So the requirements are:
I need to pass BAR into MACRO1 and it needs to be passed to MACRO2 without being expanded
The word BAR has to stay exactly as it is, I know I could use ## in order to prevent it from expanding, but then I would need to add a char to BAR and the function call wouldn't work anymore.
Is it possible to somehow get this done? Pass a macro to another macro as an argument, without the initial macro being expanded in the process?
But this code throws an error, because when MACRO1(BAR) gets
substituted with MACRO2(BAR), (BAR) then gets expanded into 3, and
MACRO2(3) leads to foo3(3)
Yes. This is the specified preprocessor behavior for your particular set of macros.
After they are identified, the arguments to a function-like macro are fully macro-expanded before being substituted into the macro's replacement text, except where they are operands of the ## or # preprocessor operator. Any appearances of those operators are evaluated, and then the resulting text is rescanned, along with any following text as appropriate, for additional macros to expand.
Is it possible to somehow get this done? Pass a macro to another macro as an argument, without the initial macro being expanded in the process?
Only where the argument is the operand of a ## or # operator. The latter doesn't help you, but the former affords a workaround: you can pass an additional, empty argument so that you can perform a concatenation without changing the wanted argument:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x,dummy) MACRO2(_x##dummy)
#define BAR 3
int main()
{
MACRO1(BAR,);
return 0;
}
That expands to
int main()
{
fooBAR(3);
return 0;
}
If you want to avoid the extra comma, then you can do so by making MACRO1 variadic:
#define MACRO2(_x) foo##_x(_x)
#define MACRO1(_x,...) MACRO2(_x##__VA_ARGS__)
#define BAR 3
int main()
{
MACRO1(BAR);
return 0;
}
That expands to the same thing as the other.
Do note that both of these approaches afford the possibility of an error being introduced by providing unwanted extra argument values to the top-level macro. One would probably suppose that most such errors would be caught at compile time, as the expansion would result in broken code, like the attempt in the question. But it is hard to rule out the possibility that such an error would coincidentally expand to something that happened to be valid, but wrong.
One way to accomplish this is to change slightly the definition of BAR.
#define MACRO2(_x) foo##_x(_x())
#define MACRO1(_x) MACRO2(_x)
#define BAR() 3
I was struggling to find an answer amoung many that refer to this topic on SO, but here's some seemingly innocent looking code that fails to compile when F is not a defined macro,
int main() {
#if defined(F) && F(0, 2, 0)
return 0;
#endif
return 1;
}
The problem, according to this section of the GCC manual is that inside #if expressions "all macros in the expression are expanded before actual computation of the expression’s value begins", so this in an invalid check, since when F is undefined, I see,
test.cpp:2:20: error: missing binary operator before token "("
#if defined(F) && F(0, 2, 0)
^
My question: is the only way to correctly do this check like so?
int main() {
#if defined(F)
#if F(0, 2, 0)
return 0;
#endif
#endif
return 1;
}
I find this quite ugly and unintuitive, so I'm hoping there's a nicer way to do such things in the preprocessor.
Assuming your F macro is defined in some header file, you could place the following code somewhere between the include and its first usage:
#ifndef F
#define F(a,b,c) 0
#endif
Or another reasonable default. That's a common solution for your problem. Another is to not allow such macros to be
not defined, but require either the default value or whatever it's expected to do. This latter approach is
a bit safer for e.g. configuration files, as it makes clear the author did consider the macro and intentionally
picked a value (i.e. he did not just forget to define it). It's also easier if the definition is in the same file.
Your test would then just be:
#if F(0, 2, 0)
Avoiding the nested condition (which would cause additional trouble if there was an #else required somewhere.
Two words of advise:
Use macros carefully and sparesely, only when reasonble. Expecially C++ provides features which reduce the need for macros.
Don't use single-letter names for macros. Remember they are textual replacements, bejond the normal language syntax. Use self-explanatory names instead (this does not only apply to macros, but for those it's even more relevant).
Seeing this question made me wonder why the approach (toy example):
#define foo(x) bar[x] = 0
would ever be preferred over the function:
void foo(unsigned x){ bar[x] = 0; }
Before the question linked above, I've only seen this once before, in the PolarSSL library, where I assumed it to be some sort of optimisation, and tried not to think too much about it.
I assume that using the preprocessor macro replaces the 'call' to be the '(not-) function body' everywhere it exists; whereas the void function may or may not be optimised out by the compiler, and therefore may result in a lot of branching for a small and simple operation or two.
Is there any other benefit?
When is the macro method preferred, and when is it better to trust the compiler?
Firstly, I'd hope your macro was actually:
#define foo(x) do { bar[x] = 0; } while (0)
for proper semicolon swallowing.
One thing in favour of macros is because you think your compiler's optimiser is not good enough. You're probably wrong. But if you've actually looked at the output carefully and know what you are doing, you might be right, which is why it's often used in the Linux kernel.
Another reason is that macros are typeless, so you might do:
#define foo(x,t) do { t[x] = 0; } while (0)
which will work for any type t. Lack of type checking is often a disadvantage, but it can be useful when defining something you want to work with any type.
Defining macro just to make the code faster is useless. A good compiler will inline
function call. However, macros can be useful when you need to use their result as constant.
#define ENCODED(a,b,c,d) (((((((a)<<8)+b)<<8)+c)<<8)+d)
switch (a) {
case ENCODED('f','o','o','0'): ...
case ENCODED('b', 'a', 'r', '1'): ...
}
When you want to define new identifiers:
#define LIB_VERSION v101
#define VERSIONNED(x) x##LIB_VERSION
void VERSIONNED(myfunction)(int x) { ... }
When you want to do some other "magics",. For example:
#define assert(x) {if ((x) == 0) {printf("%s:%d: Assertion %s failed\n", __FILE__, __LINE__, #x); exit(-1); }}
When you want to define a "generic" function working with several types. Just for illustration:
#define DELETE_LAST_ITEM(x) {while (x->next->next != NULL) x=x->next ; x->next = NULL}
and probably some other situations which I do not remember right now.
Is there any other benefit?
There are few situational benefits of using macro. Just for an example, you may use __LINE__ and __FILE__ to see where this macro is getting called for debugging.
#define foo(x) bar[x] = 0; PrintFunction("...", __FILE__,__LINE__)
The macro would never give you stronger type checking like function.
When is the macro method preferred, and when is it better to trust the compiler?
Hence, Macro should be preferred only when you don't have any choice left to use a function, because most of the times you may trust the compiler optimizer.
For some kinds of programs I need to use a constant high value to indicate some properties of some variables. I mean let color[i] = 1000000; if the i node in a tree is unexplored. But I quite often miswrite the number of 0s at the end, so I just wondered whether is it better to do it this way:
#define UNEXPLORED 1000000;
color[i] = UNEXPLORED;
I remember that somewhere I have read that it's much better to avoid using #define. Is it right? How would you tackle this problem?
For simple constants, you can use either const or the new constexpr:
constexpr unsigned int UNEXPLORED = 1000000;
In a case like this, it's no difference between using const and constexpr. However, "variables" marked constexpr are evaluated at compile-time and not at run-time, and may be used in places that otherwise only accepts literals.
For example use constants.
const unsigned int UNEXPLORED = 1000000;
or enums
enum { UNEXPLORED = 1000000 };
In the use of constants the two answers above are correct, however #define is not limited to that use alone. Another example of the use of #define is macros.
Macros
Macros are preprocessor-utilised pieces of code, and they work exactly like other #define declarations in that regard. The preprocessor will literally swap out the occurrence of your defined symbol with the code of the macro. An example:
#define HELLO_MAC do{ std::cout << "Hello World" << std::endl; }while(false)
int main(int argc, char** argv)
{
HELLO_MAC;
}
That will literally swap out the HELLO_MAC symbol with the code I declared. If it were a constant it would do the exact same thing. So you can think of #defines for constants as a particular kind of macro.
With macros you can also pass parameters, and it is especially useful I find for enforcing logging/exception policies over code.
For example
#define THROW_EXCEPT( ex_type, ex_msg ) /
do{ throw ex_type( buildExString( (ex_msg), __LINE__, __FILE__ ) ); }while(false)
...
// somewhere else
THROW_EXCEPT( std::runtime_error, "Unsupported operation in current state" );
That code allows me to ensure that everyone logs with the line of the file that threw the exception.
Templates are often a better choice instead of macros, but I cannot use template functions for this example because I need to use the __LINE__ and __FILE__ functions from the place of the throw, not from the location of the template function.
Where should you not use macros? Anywhere you can use something else. Macros, like any #define are preprocessed, so the compiler does not see them at all. This means that there is never any symbols created for HELLO_MAC or THROW_EXCEPT, and so they cannot be seen in a debugger. They can also be confusing if you get compile errors, especially if they are long macros.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When are C++ macros beneficial?
Why is #define bad and what is the proper substitute?
Someone has told me that #define is bad. Well, I honestly don't not understand why its bad. If its bad, then what other way can I do this then?
#include <iostream>
#define stop() cin.ignore(numeric_limits<streamsize>::max(), '\n');
#define is not inherently bad. However, there are usually better ways of doing what you want. Consider an inline function:
inline void stop() {
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
(Really, you don't even need inline for a function like that. Just a plain ordinary function would work just fine.)
It's bad because it's indiscriminate. Anywhere you have stop() in your code will get replaced.
The way you solve it is by putting that code into its own method.
In C++, using #define is not forcibly bad, although alternatives should be preferred. There are some context, such as include guards in which there is no other portable/standard alternative.
It should be avoided because the C preprocessor operates (as the name suggests) before the compiler. It performs simple textual replacement, without regard to other definitions. This means the result input to the compiler sometimes doesn't make sense. Consider:
// in some header file.
#define FOO 5
// in some source file.
int main ()
{
// pre-compiles to: "int 5 = 2;"
// the compiler will vomit a weird compiler error.
int FOO = 2;
}
This example may seem trivial, but real examples exist. Some Windows SDK headers define:
#define min(a,b) ((a<b)?(a):(b))
And then code like:
#include <Windows.h>
#include <algorithm>
int main ()
{
// pre-compiles to: "int i = std::((1<2)?(1):(2));"
// the compiler will vomit a weird compiler error.
int i = std::min(1, 2);
}
When there are alternatives, use them. In the posted example, you can easily write:
void stop() {
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
For constants, use real C++ constants:
// instead of
#define FOO 5
// prefer
static const int FOO = 5;
This will guarantee that your compiler sees the same thing you do and benefit you with name overrides in nested scopes (a local FOO variable will override the meaning of global FOO) as expected.
It's not necessarily bad, it's just that most things people have used it for in the past can be done in a much better way.
For example, that snippet you provide (and other code macros) could be an inline function, something like (untested):
static inline void stop (void) {
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
In addition, there are all the other things that code macros force you to do "macro gymnastics" for, such as if you wanted to call the very badly written:
#define f(x) x * x * x + x
with:
int y = f (a + 1); // a + 1 * a + 1 * a + 1 + a + 1 (4a+2, not a^3+a)
int z = f (a++); // a++ * a++ * a++ + a++
The first of those will totally surprise you with its results due to the precedence of operators, and the second will give you undefined behaviour. Inline functions do not suffer these problems.
The other major thing that macros are used for is for providing enumerated values such as:
#define ERR_OK 0
#define ERR_ARG 1
: :
#define ERR_MEM 99
and these are better done with enumerations.
The main problem with macros is that the substitution is done early in the translation phase, and information is often lost because of this. For example, a debugger generally doesn't know about ERR_ARG since it would have been substituted long before the part of the translation process that creates debugging information.
But, having maligned them enough, they're still useful for defining simple variables which can be used for conditional compilation. That's pretty much all I use them for in C++ nowadays.
#define by itself is not bad, but it does have some bad properties to it. I'll list a few things that I know of:
"Functions" do not act as expected.
The following code seems reasonable:
#define getmax(a,b) (a > b ? a : b)
...but what happens if I call it as such?:
int a = 5;
int b = 2;
int c = getmax(++a,b); // c equals 7.
No, that is not a typo. c will be equal to 7. If you don't believe me, try it. That alone should be enough to scare you.
The preprocessor is inherently global
Whenever you use a #define to define a function (such as stop()), it acts across ALL included files after being discovered.
What this means is that you can actually change libraries that you did not write. As long as they use the function stop() in the header file, you could change the behavior of code you didn't write and didn't modify.
Debugging is more difficult.
The preprocessor does symbolic replacement before the code ever makes it to the compiler. Thus if you have the following code:
#define NUM_CUSTOMERS 10
#define PRICE_PER_CUSTOMER 1.10
...
double something = NUM_CUSTOMERS * PRICE_PER_CUSTOMER;
if there is an error on that line, then you will NOT see the convenient variable names in the error message, but rather will see something like this:
double something = 10 * 1.10;
So that makes it more difficult to find things in code. In this example, it doesn't seem that bad, but if you really get into the habit of doing it, then you can run into some real headaches.