Debugging macros can take a lot of time. We are much better off avoiding them except in the very rare cases when neither constants, functions nor templates can do what we want.
What are the rare cases?
Macros are used for short operations and it avoids function call overhead. It can be used if any short operation is being done in program repeatedly. Function-like macros are very beneficial when the same block of code needs to be executed multiple times.
Speed versus size The main benefit of using macros is faster execution time. During preprocessing, a macro is expanded (replaced by its definition) inline each time it is used. A function definition occurs only once regardless of how many times it is called.
A macro (which stands for "macroinstruction") is a programmable pattern which translates a certain sequence of input into a preset sequence of output. Macros can make tasks less repetitive by representing a complicated sequence of keystrokes, mouse movements, commands, or other types of input.
You can define a macro variable within a macro, and you can also explicitly define it as a global variable, by defining it with the %GLOBAL statement. Macro variable names must start with a letter or an underscore and can be followed by letters or digits.
Below we will discuss the different methods to use Macros in excel. For adding the Developer tab in the ribbon, open an Excel workbook from the File menu. Click on Options. In a window opening up named Excel Options, click on Customize Ribbon to access the ribbon customization options. Select the Developer (Custom) option and then press on OK.
However, that code by macro recorder is often full of code that is not really needed. Also macro recorder has some limitations. So it pays to have a collection of useful VBA macro codes that you can have in your back pocket and use it when needed.
The basic rule is… if you don’t know, go for .xlsm. If we want macros to be reusable for many workbooks, often the best place to save them is in the personal macro workbook. A personal macro workbook is a hidden file which opens whenever the Excel application opens.
However .xlam (Excel Add-in), .xlsb (Excel Binary Workbook) and .xltx (Excel Macro-Enabled Template) are scenario specific formats which can also contain macros. The legacy .xls and .xla file formats can both contain macros. They were superseded in 2007, and should now be avoided. The basic rule is… if you don’t know, go for .xlsm.
If you want actual textual replacement, that's where you use macros. Take a look at Boost.Preprocessor, it's a great way to simulate variadic templates in C++03 without repeating yourself too much.
In other words, if you want to manipulate the program code itself, use macros.
Another useful application is assert
, which is defined to be a no-op when NDEBUG
is not defined (usually release mode compilation).
That brings us to the next point, which is a specialization of the first one: Different code with different compilation modes, or between different compilers. If you want cross-compiler support, you can't get away without macros. Take a look at Boost in general, it needs macros all the time because of various deficiencies in various compilers it has to support.
Another important point is when you need call-site information without wanting to bug the user of your code. You have no way to automatically get that with just a function.
#define NEEDS_INFO() \ has_info(__FILE__, __LINE__, __func__)
With a suitable declaration of has_info
(and C++11/C99 __func__
or similar).
This question doesn't appear to have a definite, closed-form answer, so I'll just give a couple of examples.
Suppose you want to print information about a given type. Type names don't exist in the compiled code, so they cannot possibly be expressed by the language itself (except for C++ extensions). Here the preprocessor must step in:
#define PRINT_TYPE_INFO(type) do { printf("sizeof(" #type ") = %zu\n", sizeof(type)); } while (false)
PRINT_TYPE_INFO(int);
PRINT_TYPE_INFO(double);
Similarly, function names are not themselves variable, so if you need to generate lots of similar names, the preprocessor helps:
#define DECLARE_SYM(name) fhandle libfoo_##name = dlsym("foo_" #name, lib);
DECLARE_SYM(init); // looks up "foo_init()", declares "libfoo_init" pointer
DECLARE_SYM(free);
DECLARE_SYM(get);
DECLARE_SYM(set);
My favourite use is for dispatching CUDA function calls and checking their return value:
#define CUDACALL(F, ARGS...) do { e = F(ARGS); if (e != cudaSuccess) throw cudaException(#F, e); } while (false)
CUDACALL(cudaMemcpy, data, dp, s, cudaMemcpyDeviceToHost);
CUDACALL(cudaFree, dp);
Since this an Open ended Question an trick which I often use and find convenient.
If you want to write an wrapper function over an free function like say malloc
, without modifying each and every instance in your code where the function is called then a simple macro shall suffice:
#define malloc(X) my_malloc( X, __FILE__, __LINE__, __FUNCTION__)
void* my_malloc(size_t size, const char *file, int line, const char *func)
{
void *p = malloc(size);
printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size);
/*Link List functionality goes in here*/
return p;
}
You can often use this trick to write your own memory leak detector etc, for debugging purposes.
Though the example is for malloc
it can be re-used for any free standing function really.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With