dbg(…)
Ein Makro für Debugging-Fans printf
-Stil.
Debugger sind großartig. Aber manchmal haben Sie einfach nicht die Zeit oder Geduld, alles richtig einzurichten und möchten einfach nur schnell einige Werte zur Laufzeit überprüfen.
Dieses Projekt stellt eine einzelne Header-Datei mit einem dbg(…)
-Makro bereit, das in allen Fällen verwendet werden kann, in denen Sie normalerweise printf("…", …)
oder std::cout << …
schreiben würden. Aber es kommt mit ein paar Extras.
# include < dbg.h >
# include < cstdint >
# include < vector >
// 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< int32_t > numbers{b, 13 , 42 };
dbg (numbers); // [example.cpp:21 (main)] numbers = {7, 13, 42} (std::vector<int32_t>)
dbg ( " this line is executed " ); // [example.cpp:23 (main)] this line is executed
factorial ( 4 );
return 0 ;
}
Der obige Code erzeugt diese Ausgabe (versuchen Sie es selbst):
std::optional
usw.dbg.h
-Header gibt eine Compiler-Warnung aus, wenn er eingefügt wird (Sie sollten also nicht vergessen, ihn zu entfernen). Um dies praktisch zu machen, sollte der dbg.h
Header von allen möglichen Orten und in allen möglichen Umgebungen leicht verfügbar sein. Der schnelle und schmutzige Weg besteht darin, die Header-Datei tatsächlich nach /usr/local/include
zu kopieren oder das Repository zu klonen und dbg.h
mit /usr/local/include/dbg.h
zu verknüpfen.
git clone https://github.com/sharkdp/dbg-macro
sudo ln -s $( readlink -f dbg-macro/dbg.h ) /usr/local/include/dbg.h
Wenn Sie keine unverfolgten Änderungen an Ihrem Dateisystem vornehmen möchten, prüfen Sie unten, ob es ein Paket für Ihr Betriebssystem oder Ihren Paketmanager gibt.
Sie können dbg-macro
vom AUR aus installieren:
yay -S dbg-macro
Sie können den dbg-macro
Port installieren über:
vcpkg install dbg-macro
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 ;
}
DBG_MACRO_DISABLE
-Flag, um das dbg(…)
-Makro zu deaktivieren (dh es zu einem No-Op-Makro zu machen).DBG_MACRO_NO_WARNING
, um die Warnungen „‚dbg.h‘-Header ist in Ihrer Codebasis enthalten“ zu deaktivieren.DBG_MACRO_FORCE_COLOR
um eine farbige Ausgabe zu erzwingen und TTY-Prüfungen zu überspringen. Sie können dem dbg(…)
-Makro mehrere Argumente übergeben. Die Ausgabe von dbg(x, y, z)
ist dieselbe wie dbg(x); dbg(y); dbg(z);
:
dbg ( 42 , " hello world " , false );
Beachten Sie, dass Sie „ungeschützte Kommas“ in Klammern setzen müssen:
dbg ( " a vector: " , (std::vector< int >{ 2 , 3 , 4 }));
Wenn Sie ganze Zahlen in hexadezimaler, oktaler oder binärer Darstellung formatieren möchten, können Sie sie einfach in dbg::hex(…)
, dbg::oct(…)
oder dbg::bin(…)
einschließen:
const uint32_t secret = 12648430 ;
dbg (dbg::hex(secret));
dbg(…)
gibt den Typ für jeden Wert bereits in Klammern aus (siehe Screenshot oben). Aber manchmal möchten Sie einfach nur einen Typ drucken (vielleicht weil Sie keinen Wert für diesen Typ haben). In diesem Fall können Sie den Helfer dbg::type<T>()
verwenden, um einen bestimmten Typ T
hübsch zu drucken. Zum Beispiel:
template < typename T>
void my_function_template () {
using MyDependentType = typename std::remove_reference<T>::type&&;
dbg (dbg::type<MyDependentType>());
}
Um einen Zeitstempel zu drucken, können Sie den Helfer dbg::time()
verwenden:
dbg (dbg::time());
Wenn Sie möchten, dass dbg(…)
für Ihren benutzerdefinierten Datentyp funktioniert, können Sie einfach operator<<
für std::ostream&
überladen:
std::ostream& operator <<(std::ostream& out, const user_defined_type& v) {
out << " … " ;
return out;
}
Wenn Sie den von dbg(…)
gedruckten Typnamen ändern möchten, können Sie eine benutzerdefinierte get_type_name
Überladung hinzufügen:
// Customization point for type information
namespace dbg {
std::string get_type_name (type_tag< bool >) {
return " truth value " ;
}
}
Wenn Sie zu dbg-macro
beitragen möchten, können Sie die Tests und Demos wie folgt erstellen:
Stellen Sie sicher, dass die Submodule auf dem neuesten Stand sind:
git submodule update --init
Verwenden Sie dann den typischen cmake
Workflow. Die Verwendung von -DCMAKE_CXX_STANDARD=17
ist optional, wird jedoch empfohlen, um den größtmöglichen Funktionsumfang zu ermöglichen:
mkdir build
cd build
cmake .. -DCMAKE_CXX_STANDARD=17
make
Um die Tests auszuführen, rufen Sie einfach Folgendes auf:
make test
Sie finden die Unit-Tests in tests/basic.cpp
.
Dieses Projekt ist von Rusts dbg!(…)
-Makro inspiriert.