Fintan
Fintan

Reputation: 51

Variable Dumping in C++

Is it possible to do a 'dump' on complex structures or even arrays in C++, in order to visually be able to check out what they've got inside them?

I'm thinking of something similar to print_r() or var_dump() in PHP.

Cheers, -Fin

Upvotes: 5

Views: 6947

Answers (7)

user5058091
user5058091

Reputation:

Why dont you use binary files? fstream has binary mode,and you can dump any type except struct,class,namespace or STL lists(like vector,queue). Wanna dump struct,class,namespace(or STL list) to binary? Make a function,and dump each variable in the file! The end! That would not be that hard... but want more help?see this code snippet!

#include <iostream>
#include <fstream>//ofstream,ifstream
using namespace std;
ifstream myBdumpin ("data.bin"/*filename*/, ios::in);//ifstream = input
ofstream myBdumpout ("data.bin"/*filename*/, ios::out);//ofstream = output
int main()
{
    char a[8]="Binary!"
    myBdumpout << a;
    char b[8];
    myBdumpin >> b;
    if(a == b)cout << "It worked!" << endl;
    else cout << "It failed..." << endl;
    return 0;
}

It should work...

Upvotes: 0

anon
anon

Reputation:

Not generally possible in C++ as it requires the use of reflection, which C++ does not have. You can of course write your own function to dump specific data structures.

Upvotes: 1

amo-ej1
amo-ej1

Reputation: 3307

Indeed, in an environment where you have gdb at your disposal and you compile your sources with debugging symbols enabled (e.g -ggdb) you can have your debugger (e.g. gdb from commandline or ddd when you want something graphically).

Consider this piece of code:

#include <string>
#include <vector>

struct test
{
    int a;
    float b;
    std::string c;
};

int main()
{
    std::vector<int> v;

    test t;
    t.a=1;
    t.b=2.0;
    t.c="hello there";


    return 0;
}

When asking gdb politely it can give me the following output:

(gdb) break 20
Breakpoint 1 at 0x8048622: file bla.cpp, line 20.
(gdb) run
Starting program: /home/edb/a.out 

Breakpoint 1, main () at bla.cpp:21
21      return 0;
(gdb) print t
$1 = {a = 1, b = 2, c = {static npos = 4294967295, 
    _M_dataplus = {> = {> = {}, }, _M_p = 0x96b6014 "hello there"}}}
(gdb) ping v
Undefined command: "ping".  Try "help".
(gdb) print v
$2 = { >> = {
    _M_impl = {> = {> = {}, }, _M_start = 0x0, _M_finish = 0x0, 
      _M_end_of_storage = 0x0}}, }

Edit: note that this data is available from a debugger context, for generating these dumps at runtime you will need to foresee your own dumping/formatting function, typically done by overloading the << operator in C++.

Upvotes: 0

i_am_jorf
i_am_jorf

Reputation: 54610

Usually debuggers are smart enough to do this.

In GDB you can use:

print structure

and in NTSD you can do the uber-cool:

dt -r structure

If you're just using this for debugging purposes, I highly recommend learning to use the debuggers. Even if its something you want to log as you (i.e. print a zillion times) you can set a breakpoint macro.

In NTSD:

bp yourdll!yourobject::yourfunction "dt -r structure;g"

And I'm sure there is a way to do it in GDB as well

Upvotes: 4

Josh Kelley
Josh Kelley

Reputation: 58382

If you add reflection to C++ (using a third-party library or vendor extensions), you can write a routine to use that reflection data to dump arbitrary structures. For example, I have some code that uses CERN's Reflex library to iterate over a class or structure's members and dump them to YAML.

Upvotes: 3

James Sutherland
James Sutherland

Reputation: 3883

In addition to the other answers, depending on what you want it for and whether you care about portability, you can potentially look at getting the information you need from the debugging information that your compiler generates. You can parse the COFF/ELF/whatever format file from the build and this gives you the information you need to work out the names and types of the variables in your object.

Upvotes: 3

j_random_hacker
j_random_hacker

Reputation: 51246

The short answer is: no, unless you manually write such a routine yourself.

Which is often not a bad idea, but it has the usual problems of getting out of sync with the class if you are adding/changing members often. This is unavoidable because C++ lacks any form of introspection into structs.

If you decide to go that way, the best thing to do is to write an overload for std::ostream& operator<<(std::ostream& os, MyClass const&), which will enable your class to be printed to any IOStreams output stream.

Upvotes: 8

Related Questions