Thread: Dynamic struct alignment?

  1. #1
    Registered User
    Join Date
    Jun 2007
    Location
    Michigan
    Posts
    12

    Dynamic struct alignment?

    Greetings,

    How might you go about determining the alignment of a struct at runtime? I need to be able to read (at runtime) a struct definition, fill it with data, write it to a disk file - then in another program that has the structure actually defined at compile time, read the data from the disk file and populate the struct.

    In the program with the struct defined at compile time, alignment will be taken care of by the compiler. On the side where I need to allow for a dynamic definition (either interactively or via reading the struct from a given config file related to the app), how do I write the data in the same way in which it will be aligned in the other program?

    Is my description clear? It's harder than I thought to explain. ;-)

    Matthew

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Your description is very clear.

    As far as I know, there's no way to dynamically change structure alignment. At least no portable way. It would probably affect how the stack worked, so I don't know if it would be possible. But I don't know much about that sort of thing.

    You might have to do it by hand. For example, if a structure contained
    Code:
    struct s {
        char c;
        int x;
    };
    and was aligned to a 32-bit boundary, such a structure written to a binary file would be 1 (for c) + 3 (for padding) + 4 (for x) bytes. You could read this in, one byte for c, skip three bytes for padding, and four bytes for x. You'd have to be careful about edianness for fields larger than one byte, unless you want to make the assumption that it will always be the same.

    But really, if you need to transfer data between programs with different structure alignment, you shouldn't be using binary files. They're just more hassle than they're worth. Can you use text files instead?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    Jun 2007
    Location
    Michigan
    Posts
    12
    Well, let me explain the situation, maybe there is a better way all together.

    First, the platform will not change, and I'm not worried about byte order. The files will be created and used on the same machine (a SPARC IV running Solaris 10 if you want to know).

    What I'm doing is building a bunch of lookup tables to support another program that uses the lookup tables. The lookups are using the Berkeley DB package and records are simply stored as blobs of data (you pass a pointer and a size). Thus, when creating the database file, one could specify a struct and its size, and everything would be fine for the other program that uses the lookup; simply use the same struct and the records come back intact.

    However (you knew it was coming). I have a *lot* of these lookup tables to create and maintain, plus other people could use the lookup table tool. So I wanted to be able to define the record structure in a text file that the lookup creation tool could read and then build the database. Thus, the struct is not known at compile time. Well, it could be, but that makes the tool a lot less usable and I might as well stick with brute-force programs to just build the specific tables to begin with.

    I want to keep the structs aligned so they are easier to deal with in the programs that require the lookups.

    So basically I'd like to be able to read a config file or interactive commands and build a database record that will be stored on disk as an aligned struct.

    Matthew

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    If you don't know what is in the structure at compile time, then you probably don't have to worry about structure alignment. Because you don't know what's in the structure, you might have to use an array of void pointers to store the data, or a linked list of structures. Or something like that. Anyway, the fields would probably all be pointers, so the alignment would be different than the original structure. And you wouldn't be able to use fread either, unless you knew the structure's contents at compile-time.

    Since you can't use fread(), you'd have to read it in manually, so you could implement the structure alignment in that code. Basically, if the alignment is four bytes but a variable only takes up three, read in an extra byte and discard it.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    If it's all confined to the same machine, then create a library which performs all the record access types you need to support, then get all the programs to link to that library.

    Then everything will be consistent.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Jun 2007
    Location
    Michigan
    Posts
    12
    I think I'm confusing the questions. Basically it goes like this:

    1. Lookup data exists in a flat binary file (can't do anything about this).
    2. Create a struct for source binary format.
    3. Create a struct for the database record format (might not need all the fields in the original source, plus desire alignment for speed of member access.)
    4. Read source data and populate db record struct and the key field.
    5. Call database "write" function to add the record.

    Now I have a b-tree database lookup table that I use in another program:

    1. Include db record struct in code.
    2. Open db.
    3. Use db by passing a key and a pointer to the record struct to the lookup function.
    4. DB lookup populates the struct
    5. Use struct.

    What I want to change is the first set of steps because I have a lot of lookup tables to create, and other people where I work have lookup tables to create also. Currently the lookup table creation programs are specific to each source file and record struct, so if I have 20 lookup tables then I have 20 programs to build them. Kind of a pain in the butt.

    Thus, I'd like to make a generic lookup table tool that can read the format of the source file, db record struct, and key offset from a sort of config file. Then to build a new lookup table all I have to do it add another definition to the config file and run the single tool. Of course in the second part, the program that uses the lookup table I will have to include the record structs - that's fine, there is nothing I can do about that (well there is, but speed is a priority, thus wanting aligned structs in the lookup tables).

    Matthew

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Correct me if I'm wrong, but you want to create a structure that can contain any data. You might employ something like this:
    Code:
    enum type_t {
        TYPE_CHAR,
        TYPE_INT,
        TYPE_STRING,
        /* ... */
    };
    
    struct data_t {
        void *data;
        enum type_t type;
    };
    
    struct structure_t {
        struct data_t **member;
        size_t members;
    };
    Is that right?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    Jun 2007
    Location
    Michigan
    Posts
    12
    Yup, that would be a good way to start. Your example also made me think a little more into the future with this "tool" and I'm coming up with things I totally forgot about. I'm going to shelve it for now, I just don't have enough time to write it and do my priority work.

    Thanks everyone for the feedback, hopefully I'll get some time to work this out at a later date.

    @dwks: I'm going to have to check out some of your programs. I've always had a big interest in mazes and I'm currently working on a project or two using SDL.

    M@

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamic access to components of a struct
    By Kempelen in forum C Programming
    Replies: 1
    Last Post: 04-01-2009, 04:18 AM
  2. Replies: 1
    Last Post: 12-03-2008, 03:10 AM
  3. Search Engine - Binary Search Tree
    By Gecko2099 in forum C Programming
    Replies: 9
    Last Post: 04-17-2005, 02:56 PM
  4. Dynamic memory alloction for my array of struct
    By pears0 in forum C Programming
    Replies: 13
    Last Post: 03-11-2005, 11:53 AM
  5. struct dynamic memory allocation
    By rotis23 in forum C Programming
    Replies: 2
    Last Post: 12-09-2002, 04:31 AM