• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
ultramailman

struct alignment question

9 posts in this topic

Hallo.

I understand that the size of a struct is not always the sum of it's innards, because there can be padding inbetween fields. What I am wondering is this:

Can I safely assume that two differently named structs types are the same (have the same size and same field offset) if they have the same arrangement of fields?

That is, can I assume that these two are the same:
struct a{
    int a;
    char b;
    long c;
    short d;
    double e;
};

struct a{
    int a;
    char b;
    long c;
    short d;
    double e;
};
even when they are defined in completely different places (different files, or different scope, or maybe anonymously defined)?
0

Share this post


Link to post
Share on other sites

Yes and no ;)

 

The names of the fields doesn't matter, just the type and ordering, so yes.

 

But you can change the packing with #pragma pack (or with a compile time switch) (on Visual C++ anyway, other compilers may have different options/pragmas), so no. The alignment can be different when the source or header file is compiled depending on what packing is active when the struct/class definition is parsed.

Edited by Paradigm Shifter
1

Share this post


Link to post
Share on other sites

Can I safely assume that two differently named structs types are the same (have the same size and same field offset) if they have the same arrangement of fields?  That is, can I assume that these two are the same, even when they are defined in completely different places (different files, or different scope, or maybe anonymously defined)?

Yes, their layout in memory should be the same.

 

For example, if you include the same structure declaration in various source files the objects must be interchangeable because they are the same layout.  If you have the object in foo.c and also in bar.c, you can pass the objects between functions in either file without problem.

 

 

 

As Paradigm Shifter pointed out, you can mess this up on your own by changing the alignment or padding options for the compiler, but that breaks lots of things.  Don't do that.

0

Share this post


Link to post
Share on other sites

The bigger question is WHY you would have 2 identical structs defined in multiple places which you wanted to treat as the same in multiple places. That's what header files are for.

0

Share this post


Link to post
Share on other sites
Ah, so as long as I don't use pragmas or __attribute__, it should be the same.

The reason I'm doing this is for convenience (and I'd say clarity of the code too).

I have this hash set type, and it can be used as a hash table if I just pass in a pair of values as a key. The thing is, I need to define a new struct for every pair (no std::pair<a, b> template in c). Rather than defining them at the top of the file with names that I might not remember, I think it is better to define it in the function where I actually need to use it.
0

Share this post


Link to post
Share on other sites

What does your implementation for your hash map look like? Does it use void* and size parameters or is it built with #define macros?

 

You might be better off defining an interface of function pointers instead and use that in the same way you would an abstract class in C++, (i.e. a list of function pointers like a vtbl) and passing one of those in to the create function of your hash map (which would be stored in the map and would call out to functions provided by concrete implementations for each type, like how qsort does for the comparison operator). Then your concrete implementations can cast from void* to the required type and back.

 

Or you could just use C++ ;)

0

Share this post


Link to post
Share on other sites
It looks like this:
When I create a new hash set, I pass in the element size, a comparison function pointer, and a hash function pointer. Adding a key involves using memcpy to copy "element size" number of bytes into the hash set's array. So yes, it's void* and element size.

Basically, I un-macro-ized the original macro implementation because it was getting messy to put things like "MAKE_HASHSET(int, INT_CMP, INTHASH)" everywhere.

The vtable you described there, what function pointer is needed? (besides comparison and hash) Edited by ultramailman
0

Share this post


Link to post
Share on other sites

That should do it (comparison and hash).

 

You can also store the element size and keysize when you create the hash map, then you can express the entire interface using void*, but you do lose the ability to use a literal key then (need to use a variable with an address).

 

hashmap* pMap = CreateHashSet(sizeof(int) /*keysize*/, sizeof(int) /* element size */, INT_CMP /* comparison func */. INTHASH /* hash func */);

 

int myKey = 0;

int myValue = 42;

pMap->InsertElement(&myKey, &myValue);

 

where the insert uses sizeof(int) stored as the keysize to copy the element, and InsertElement just uses void* parameters (size is known by the data associated with the map).

Edited by Paradigm Shifter
0

Share this post


Link to post
Share on other sites
That's pretty much how it is. Except it only takes keys as an argument.
/* inside a function*/
typedef struct int_pair{
    int key, val;
}int_pair;
struct hashset * hs = hashset_new(sizeof(int_pair), &int_cmp, &int_hash);
hashset_insert(hs, &(int_pair){0, 42});
It's true that it can't take literals, but it still behaves as if it is because it does make a copy of the thing.
0

Share this post


Link to post
Share on other sites

The bigger question is WHY you would have 2 identical structs defined in multiple places which you wanted to treat as the same in multiple places. That's what header files are for.

In fact, that's what header files DO.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0