GitHub - sharkdp/dbg-macro: A dbg(…) macro for C++ (original) (raw)

dbg(…)

Build status Try it online License: MIT

A macro for printf-style debugging fans.

Debuggers are great. But sometimes you just don't have the time or patience to set up everything correctly and just want a quick way to inspect some values at runtime.

This projects provides a single header file with a dbg(…)macro that can be used in all circumstances where you would typically writeprintf("…", …) or std::cout << …. But it comes with a few extras.

Examples

#include <dbg.h> #include #include

// You can use "dbg(..)" in expressions: int32_t factorial(int32_t n) { if (dbg(n <= 1)) { return dbg(1); } else { return dbg(n * factorial(n - 1)); } }

int32_t main() { std::string message = "hello"; dbg(message); // [example.cpp:15 (main)] message = "hello" (std::string)

const int32_t a = 2; const int32_t b = dbg(3 * a) + 1; // [example.cpp:18 (main)] 3 * a = 6 (int32_t)

std::vector numbers{b, 13, 42}; dbg(numbers); // [example.cpp:21 (main)] numbers = {7, 13, 42} (std::vector)

dbg("this line is executed"); // [example.cpp:23 (main)] this line is executed

factorial(4);

return 0; }

The code above produces this output (try it yourself):

dbg(…) macro output

Features

Installation

To make this practical, the dbg.h header should be readily available from all kinds of different places and in all kinds of environments. The quick & dirty way is to actually copy the header file to /usr/local/include or to clone the repository and symlink dbg.h to /usr/local/include/dbg.h.

git clone https://github.com/sharkdp/dbg-macro sudo ln -s $(readlink -f dbg-macro/dbg.h) /usr/local/include/dbg.h

If you don't want to make untracked changes to your filesystem, check below if there is a package for your operating system or package manager.

On Arch Linux

You can install dbg-macro from the AUR:

With vcpkg

You can install the dbg-macro port via:

With cmake

CMakeLists.txt

cmake_minimum_required(VERSION 3.11) # FetchContent added in cmake 3.11 project(app) # name of executable

set(CMAKE_CXX_STANDARD 17)

dbg-macro

include(FetchContent)

FetchContent_Declare(dbg_macro GIT_REPOSITORY https://github.com/sharkdp/dbg-macro) FetchContent_MakeAvailable(dbg_macro)

add_executable(${PROJECT_NAME} main.cpp) # your source files goes here target_link_libraries(${PROJECT_NAME} PRIVATE dbg_macro) # make dbg.h available

main.cpp

#include <dbg.h>

int main() { dbg(42, "hello world", false); return 0; }

Configuration

Advanced features

Multiple arguments

You can pass multiple arguments to the dbg(…) macro. This will output all expressions on a single line.

dbg(42, "hello world", false);

Note that you have to wrap "unprotected commas" in parentheses:

dbg("a vector:", (std::vector{2, 3, 4}));

If you want to output expressions each on its own line write dbg(x); dbg(y); dbg(z); instead of dbg(x, y, z).

Hexadecimal, octal and binary format

If you want to format integers in hexadecimal, octal or binary representation, you can simply wrap them in dbg::hex(…), dbg::oct(…) or dbg::bin(…):

const uint32_t secret = 12648430; dbg(dbg::hex(secret));

Printing type names

dbg(…) already prints the type for each value in parenthesis (see screenshot above). But sometimes you just want to print a type (maybe because you don't have a value for that type). In this case, you can use the dbg::type<T>() helper to pretty-print a given type T. For example:

template void my_function_template() { using MyDependentType = typename std::remove_reference::type&&; dbg(dbg::type()); }

To print a timestamp, you can use the dbg::time() helper:

Customization

If you want dbg(…) to work for your custom datatype, you can simply overload operator<< forstd::ostream&:

std::ostream& operator<<(std::ostream& out, const user_defined_type& v) { out << "…"; return out; }

If you want to modify the type name that is printed by dbg(…), you can add a customget_type_name overload:

// Customization point for type information namespace dbg { std::string get_type_name(type_tag) { return "truth value"; } }

Development

If you want to contribute to dbg-macro, here is how you can build the tests and demos:

Make sure that the submodule(s) are up to date:

git submodule update --init

Then, use the typical cmake workflow. Usage of -DCMAKE_CXX_STANDARD=17 is optional, but recommended in order to have the largest set of features enabled:

mkdir build cd build cmake .. -DCMAKE_CXX_STANDARD=17 make

To run the tests, simply call:

You can find the unit tests in tests/basic.cpp.

Acknowledgement

This project is inspired by Rusts dbg!(…) macro.