dbg(…)
Uma macro para fãs de depuração no estilo printf
.
Os depuradores são ótimos. Mas às vezes você simplesmente não tem tempo ou paciência para configurar tudo corretamente e só quer uma maneira rápida de inspecionar alguns valores em tempo de execução.
Este projeto fornece um único arquivo de cabeçalho com uma macro dbg(…)
que pode ser usada em todas as circunstâncias em que você normalmente escreveria printf("…", …)
ou std::cout << …
. Mas vem com alguns 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 ;
}
O código acima produz esta saída (tente você mesmo):
std::optional
, etc.dbg.h
emite um aviso do compilador quando incluído (para que você não se esqueça de removê-lo). Para tornar isso prático, o cabeçalho dbg.h
deve estar prontamente disponível em todos os tipos de locais e em todos os tipos de ambientes. A maneira rápida e suja é copiar o arquivo de cabeçalho para /usr/local/include
ou clonar o repositório e criar um link simbólico dbg.h
para /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
Se você não quiser fazer alterações não rastreadas em seu sistema de arquivos, verifique abaixo se existe um pacote para seu sistema operacional ou gerenciador de pacotes.
Você pode instalar dbg-macro
do AUR:
yay -S dbg-macro
Você pode instalar a porta dbg-macro
via:
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
para desabilitar a macro dbg(…)
(ou seja, para torná-la autônoma).DBG_MACRO_NO_WARNING
para desativar os avisos "O cabeçalho 'dbg.h' está incluído em sua base de código" .DBG_MACRO_FORCE_COLOR
para forçar a saída colorida e ignorar as verificações de tty. Você pode passar vários argumentos para a macro dbg(…)
. A saída de dbg(x, y, z)
é igual a dbg(x); dbg(y); dbg(z);
:
dbg ( 42 , " hello world " , false );
Observe que você deve colocar "vírgulas desprotegidas" entre parênteses:
dbg ( " a vector: " , (std::vector< int >{ 2 , 3 , 4 }));
Se você deseja formatar números inteiros em representação hexadecimal, octal ou binária, você pode simplesmente envolvê-los em dbg::hex(…)
, dbg::oct(…)
ou dbg::bin(…)
:
const uint32_t secret = 12648430 ;
dbg (dbg::hex(secret));
dbg(…)
já imprime o tipo de cada valor entre parênteses (veja a imagem acima). Mas às vezes você deseja apenas imprimir um tipo (talvez porque não tenha um valor para esse tipo). Nesse caso, você pode usar o auxiliar dbg::type<T>()
para imprimir um determinado tipo T
. Por exemplo:
template < typename T>
void my_function_template () {
using MyDependentType = typename std::remove_reference<T>::type&&;
dbg (dbg::type<MyDependentType>());
}
Para imprimir um carimbo de data/hora, você pode usar o auxiliar dbg::time()
:
dbg (dbg::time());
Se você deseja que dbg(…)
funcione para seu tipo de dados personalizado, você pode simplesmente sobrecarregar operator<<
para std::ostream&
:
std::ostream& operator <<(std::ostream& out, const user_defined_type& v) {
out << " … " ;
return out;
}
Se quiser modificar o nome do tipo impresso por dbg(…)
, você pode adicionar uma sobrecarga get_type_name
personalizada:
// Customization point for type information
namespace dbg {
std::string get_type_name (type_tag< bool >) {
return " truth value " ;
}
}
Se você quiser contribuir com dbg-macro
, veja como você pode construir os testes e demonstrações:
Certifique-se de que os submódulos estejam atualizados:
git submodule update --init
Em seguida, use o fluxo de trabalho típico cmake
. O uso de -DCMAKE_CXX_STANDARD=17
é opcional, mas recomendado para ter o maior conjunto de recursos habilitado:
mkdir build
cd build
cmake .. -DCMAKE_CXX_STANDARD=17
make
Para executar os testes, basta chamar:
make test
Você pode encontrar os testes de unidade em tests/basic.cpp
.
Este projeto é inspirado na macro Rusts dbg!(…)
.