Overwriting an entire class from a disk record

Discussion in 'C++' started by Dom Bannon, Oct 5, 2010.

  1. Dom Bannon

    Dom Bannon Guest

    Is this ever possible?

    More specifically, I have a simple disk record which is, say, 64 bytes
    long. Currently, I have a class which defines various members
    corresponding to the fields in this record, and the class is
    responsible for writing itself to/reading itself from disk.

    This is fine, but it's inefficient. Ideally, I'd like to fread in 64
    bytes directly on top of a class instance, or fwrite out 64 bytes from
    the address of the class, pretending that it's a C struct.

    I can clearly get this to work in simple cases where I use a member
    address instead of a class address - for example, my class might
    contains one member, which is a 64-byte array, or it might contain a
    union, one element of which is a 64-byte array. Would this work for
    more complex cases? Presumably there's no guarantee that the address
    of a class is the address of it's first member?

    Thanks -

    Dom
    Dom Bannon, Oct 5, 2010
    #1
    1. Advertising

  2. Dom Bannon

    Goran Guest

    On Oct 5, 11:05 am, Dom Bannon <> wrote:
    > Is this ever possible?
    >
    > More specifically, I have a simple disk record which is, say, 64 bytes
    > long. Currently, I have a class which defines various members
    > corresponding to the fields in this record, and the class is
    > responsible for writing itself to/reading itself from disk.
    >
    > This is fine, but it's inefficient. Ideally, I'd like to fread in 64
    > bytes directly on top of a class instance, or fwrite out 64 bytes from
    > the address of the class, pretending that it's a C struct.
    >
    > I can clearly get this to work in simple cases where I use a member
    > address instead of a class address - for example, my class might
    > contains one member, which is a 64-byte array, or it might contain a
    > union, one element of which is a 64-byte array. Would this work for
    > more complex cases? Presumably there's no guarantee that the address
    > of a class is the address of it's first member?


    AFAIK, in C++, you can do that "safely" only if you use "plain ol'
    data" type.

    But that's good enough already, and that's your entry door for these
    kinds of things. Just define your struct so that it's "layout-
    compatible" with what you have on disk, and then read/write into that
    from a given binary stream. You can then wrap the struct into a class
    or through containment (or perhaps inheritance, too).

    E.g.

    struct POD
    {
    // Must match platform alignment requirement, though.
    // Not sure that data[64] will actually be 64 bytes or anything.
    char data[64];
    };

    class data
    {
    private:
    POD raw_data;
    public:
    void member_fn(){}
    }

    Goran.
    Goran, Oct 5, 2010
    #2
    1. Advertising

  3. Dom Bannon wrote:
    > Is this ever possible?
    >
    > More specifically, I have a simple disk record which is, say, 64 bytes
    > long. Currently, I have a class which defines various members
    > corresponding to the fields in this record, and the class is
    > responsible for writing itself to/reading itself from disk.
    >
    > This is fine, but it's inefficient. Ideally, I'd like to fread in 64
    > bytes directly on top of a class instance, or fwrite out 64 bytes from
    > the address of the class, pretending that it's a C struct.


    Just make sure the class is POD, and go ahead.

    >
    > I can clearly get this to work in simple cases where I use a member
    > address instead of a class address - for example, my class might
    > contains one member, which is a 64-byte array, or it might contain a
    > union, one element of which is a 64-byte array. Would this work for
    > more complex cases? Presumably there's no guarantee that the address
    > of a class is the address of it's first member?


    Do you have an example? What is the "more complex case" for you?
    Vladimir Jovic, Oct 5, 2010
    #3
  4. Dom Bannon

    gwowen Guest

    On Oct 5, 12:12 pm, Vladimir Jovic <> wrote:

    > > This is fine, but it's inefficient. Ideally, I'd like to fread in 64
    > > bytes directly on top of a class instance, or fwrite out 64 bytes from
    > > the address of the class, pretending that it's a C struct.

    >
    > Just make sure the class is POD, and go ahead.
    >


    Can't one make a POD class with all the data in it, and then derive
    from that to add member functions? Surely the LSP guarantees that the
    layout of the first sizeof(POD_class) bytes are identical to the
    POD_class itself.
    gwowen, Oct 5, 2010
    #4
  5. gwowen wrote:
    > On Oct 5, 12:12 pm, Vladimir Jovic <> wrote:
    >
    >>> This is fine, but it's inefficient. Ideally, I'd like to fread in 64
    >>> bytes directly on top of a class instance, or fwrite out 64 bytes from
    >>> the address of the class, pretending that it's a C struct.

    >> Just make sure the class is POD, and go ahead.
    >>

    >
    > Can't one make a POD class with all the data in it, and then derive
    > from that to add member functions? Surely the LSP guarantees that the
    > layout of the first sizeof(POD_class) bytes are identical to the
    > POD_class itself.


    I am not sure why do you want to derive from POD. Off course you can,
    but you can add member functions to the POD structure. (At least that is
    what I am doing in my code)

    The layout is the same, only if the derived class is empty (has no
    member variables).
    Vladimir Jovic, Oct 5, 2010
    #5
  6. Dom Bannon

    Dom Bannon Guest

    On Tue, 05 Oct 2010 13:12:43 +0200, Vladimir Jovic
    >Just make sure the class is POD, and go ahead.
    > ...
    >Do you have an example? What is the "more complex case" for you?


    When you say a POD class, presumably you just mean that the class
    contains POD members? The actual case looks like this:

    struct A {
    uint64_t b;
    uint16_t c;
    uint8_t d[X];
    ... more POD (int) members here
    };

    It might be convenient to put some member functions in, though that's
    not really necessary.

    Thanks -

    Dom
    Dom Bannon, Oct 5, 2010
    #6
  7. Dom Bannon

    gwowen Guest

    On Oct 5, 12:35 pm, Vladimir Jovic <> wrote:

    > I am not sure why do you want to derive from POD. Off course you can,
    > but you can add member functions to the POD structure. (At least that is
    > what I am doing in my code)
    >
    > The layout is the same, only if the derived class is empty (has no
    > member variables).


    Really? I can't see how the layout of the base class can be rearranged
    in the derived class, and yet still.

    // pod.hpp

    class Pod {
    int i;
    double d;
    }

    void frobnicate(Pod* p);

    // Pod.cpp
    void frobnicate(Pod* p)
    {
    p->i = 3;
    p->d = 7.0;
    }


    // dpod.cpp
    class DPod : public Pod {
    private:
    std::string unique_id;
    }

    void f(void)
    {
    DPod d;
    frobnicate(&d);
    }

    I'm aware that in multiple-inheritance cases the compiler will have to
    mangle the pointer, but with single inheritance, is there really no
    guarantee that this will *not* happen.
    gwowen, Oct 5, 2010
    #7
  8. Dom Bannon

    Dom Bannon Guest

    On Tue, 05 Oct 2010 12:39:29 +0100, Dom Bannon <>
    wrote:

    >struct A {
    > uint64_t b;
    > uint16_t c;
    > uint8_t d[X];
    > ... more POD (int) members here
    >};


    Well, I've tried it, and it works (at least on gcc/Linux/x86) -
    Thanks. Various member functions, but only POD data.

    -Dom
    Dom Bannon, Oct 5, 2010
    #8
  9. Dom Bannon

    Goran Guest

    On Oct 5, 1:18 pm, gwowen <> wrote:
    > On Oct 5, 12:12 pm, Vladimir Jovic <> wrote:
    >
    > > > This is fine, but it's inefficient. Ideally, I'd like to fread in 64
    > > > bytes directly on top of a class instance, or fwrite out 64 bytes from
    > > > the address of the class, pretending that it's a C struct.

    >
    > > Just make sure the class is POD, and go ahead.

    >
    > Can't one make a POD class with all the data in it, and then derive
    > from that to add member functions?  Surely the LSP guarantees that the
    > layout of the first sizeof(POD_class) bytes are identical to the
    > POD_class itself.


    I think that's correct. But the problem is what happens when you add
    member functions. I don't think that standard makes any guarantee that
    derived stays of same size, even if there's no virtual functions.
    Therefore you can't use an array of derived objects to read in a block
    (which, frankly, I think is a shame and wish I was wrong ;-)).

    I also think that (sadly) Vladimir is theoretically incorrect in
    saying that you can add member functions to a POD. But in practice,
    he's right. E.g. adding members on gcc, msc and intel compilers on x86
    works.

    Goran.
    Goran, Oct 6, 2010
    #9
  10. Dom Bannon

    James Kanze Guest

    On Oct 6, 11:30 am, Goran <> wrote:
    > On Oct 5, 1:18 pm, gwowen <> wrote:


    > > On Oct 5, 12:12 pm, Vladimir Jovic <> wrote:


    > > > > This is fine, but it's inefficient. Ideally, I'd like to
    > > > > fread in 64 bytes directly on top of a class instance,
    > > > > or fwrite out 64 bytes from the address of the class,
    > > > > pretending that it's a C struct.


    > > > Just make sure the class is POD, and go ahead.


    > > Can't one make a POD class with all the data in it, and then
    > > derive from that to add member functions? Surely the LSP
    > > guarantees that the layout of the first sizeof(POD_class)
    > > bytes are identical to the POD_class itself.


    > I think that's correct. But the problem is what happens when
    > you add member functions. I don't think that standard makes
    > any guarantee that derived stays of same size, even if there's
    > no virtual functions. Therefore you can't use an array of
    > derived objects to read in a block (which, frankly, I think is
    > a shame and wish I was wrong ;-)).


    I haven't looked at it in detail, but I think that the next
    version of the standard will make some additional guarantees
    with regards to layout.

    > I also think that (sadly) Vladimir is theoretically incorrect
    > in saying that you can add member functions to a POD. But in
    > practice, he's right. E.g. adding members on gcc, msc and
    > intel compilers on x86 works.


    The presence of member functions doesn't stop a type from being
    a PODS. To be a PODS, it is sufficient that the class doesn't
    have any user defined constructors, destructors or copy
    assignment, base classes, virtual functions, or members that
    aren't PODs or references.

    --
    James Kanze
    James Kanze, Oct 6, 2010
    #10
  11. Dom Bannon

    Jorgen Grahn Guest

    On Tue, 2010-10-05, Dom Bannon wrote:
    > Is this ever possible?


    (Please repeat the question in the Subject: header ("Overwriting an
    entire class from a disk record") in the body of the message, so it's
    more readable and can be quoted and commented on.)

    You're confusing class and object. If you had written

    "Overwriting an entire object from a disk record"

    I would have understood what you were talking about (except modern
    file systems aren't record-based, so I'd probably stop and wonder if
    you're working on some IBM big-iron system).

    The actual *question* has been deduced and answered by others, so I
    won't try myself.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Oct 7, 2010
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jas Shultz
    Replies:
    0
    Views:
    936
    Jas Shultz
    Dec 3, 2003
  2. Peter Grison
    Replies:
    3
    Views:
    521
    Roedy Green
    Apr 27, 2004
  3. Blankdraw

    Can't read entire record - fscanf (choked up)

    Blankdraw, Aug 25, 2003, in forum: C Programming
    Replies:
    2
    Views:
    525
    Eric Sosman
    Aug 27, 2003
  4. Replies:
    12
    Views:
    505
    santosh
    Nov 15, 2006
  5. katthi
    Replies:
    2
    Views:
    83
    Gregory Brown
    May 29, 2007
Loading...

Share This Page