corner imagecorner image
IDEPlatformPluginsDocs & SupportCommunityPartners

Exploring Macros in C/C++ Projects - NetBeans IDE 6.7/6.8 Tutorial

This tutorial shows you how to use new NetBeans IDE 6.7/6.8/6.9 features for investigating and debugging code that includes macros.

Contents

Content on this page applies to NetBeans IDE 6.7/6.8/6.9

Requirements

To follow this tutorial, you need the following software and resources.

Software or Resource Version Required
NetBeans IDE version 6.7, 6.8, or 6.9 with NetBeans C/C++ plugin module
Java Developer Kit (JDK) version 6
C and C++ compilers, make, gdb

C/C++ Tool Collections Tested with NetBeans IDE

See the NetBeans IDE 6.8 Installation Instructions and Configuring the NetBeans IDE for C/C++/Fortran
for information about downloading and installing the required software.

Investigating Code That Uses Macros

In previous versions of the NetBeans IDE, macros were hyperlinked so that you could click on them to see their expansion, which would cause the IDE to open the header file where the macro was defined. This approach is not convenient for simple macros such as numerical constants or string literals when you just want a quick look at its definition.

NetBeans IDE 6.7 introduced two features for exploring source code that contains macros:

  • Macro tooltips, useful for short and simple macros
  • Macro expansion view, useful for more complex macros

Working with simple macros using macro tooltips

The tooltips for macros allow you to view a small popup without opening another file.

To activate a macro tooltip so you can see its expansion:

  1. Press Ctrl+Alt.
  2. Place the mouse cursor on the macro you want to expand, and a tooltip opens to display the expanded information.
  3. If you want more information, click the macro while pressing Ctrl+Alt to open a Macro Expansion window that shows the function with the macro expanded.

Macro tooltip expansion

Working with complex macros using Macro Expansion View

The Macro Expansion View enables you to investigate source code with complex multiple-line macros. Macros are often used to define constants, but can also be used to define code fragments that can be used like functions. When you work with code that uses macros in this way, it might be difficult to understand what is happening in the code. You may need to examine the macros in context with the source code that is calling the macro.

To view the source code with expanded macro code:

  • Right-click on the macro and select Navigate->View Macro Expansion from the pop-up menu.
    The Macro Expansion window opens to display the expanded macro in context with the code that calls it.
  • You can also mouse over the code of interest while pressing Ctrl+Alt, and click the hyperlink.

Macro expansion view

In the Macro Expansions window, the macro contents are located inside guarded blocks. Semantic highlighting is provided for expanded code. You can use hyperlinks in Macro Expansion view to go to other source files. Also there is highlighting for macro parameter usages.

The left column of the Macro Expansion window includes several toolbar buttons:

  • Synchronize caret, content and context
    This option synchronizes caret position and content in the source file in the Editor window and in the Macro Expansion view.
    It also changes context to make it relevant to caret position (if expand local context only selected).
  • Expand local context only Only the macros in the code block where the caret is located are expanded in the Macro Expansion window.
  • Expand whole file
    All macros in the source file are expanded in the Macro Expansion window.
  • Up and down arrows
    These buttons are for quick navigation to go to the next macro or go to the previous macro.

Debugging Code That Uses Macros

Sometimes it's not enough to understand the meaning of a macro.
Let's take a look at a simple example:

#include <stdlib.h>
#include <iostream>

#define ID_FIRST (0)
#define ID_ALICE (ID_FIRST)
#define ID_BOB (ID_ALICE + 1)
#define ID_TOM (ID_BOB + 1)
#define ID_FRINDS_NUMBER (ID_TOM + 1)

#define NEXT_PERSON(id) (id + 1)
#define PREV_PERSON(id) (id - 1)

using namespace std;

/*
* Main function
*/
int main(int argc, char** argv) {
int person = ID_TOM;
if (NEXT_PERSON(person) == ID_FRINDS_NUMBER) {
cout << "last person";
}
return (EXIT_SUCCESS);
}

Imagine that we stopped the debugger on the if statement and we want to know if the program will print "last person" or not.

Macro expansion tooltip says that ID_FRINDS_NUMBER is "(((((0))+ 1)+ 1)+ 1)".
Great, but how much is it? In this simple situation it's easy to say that it's 3, but imagine that we have two thousand persons.

Evaluating macros using tooltips

Now it's possible to use expression evaluation on expressions with macros too.
Just hover ID_FRINDS_NUMBER and you'll see:

Macro expression evaluation

Also it's possible to evaluate whole expression:

Macro expression evaluation

Be careful evaluating macros in tooltips, because such evaluation can change state of program. For example evaluating of macro that expands to i++ will increment i;

Using watches for evaluating macros

Now it's possible to use macros in debugger watches:

Macro debugging watches

Be careful evaluating macros in watches, because such evaluation can change state of program. For example evaluating of macro that expands to i++ will increment i;