That's what CornedBee meant. You can't do it portably; you have to assume things like structure padding. You shouldn't be writing code that relies on this sort of thing, unless you're doing something pretty unusual.

If I'm not mistaken, the compiler is responsible for the padding, not something else. You can force a compiler or set it in the options to set padding. Or you can just write a mechanism to parse memory and figure it out. Either way, it does become portable.
And actually, I have once written something "unusual" that does something like this...

I was writing a small library for DirectInput w/ action feedback or whatever it's called. The program registered what keys it wanted to intercept and passed along a struct of bool values and the number of keys it has registered, that were set to true if key was pressed down and false if not.
Since the library had no idea of the contents of the struct, I used a raw memory approach. If key 4 was pressed, set beginning_of_struct + 4 to true, and so on.
Why did I do this? Why not an array or something? The approach to this is that the calling program can define the structure however they want as long as there's one member for each key. Then you can name the members whatever instead of a generic "bool key4;"

If I'm not mistaken, the compiler is responsible for the padding, not something else. You can force a compiler or set it in the options to set padding. Or you can just write a mechanism to parse memory and figure it out. Either way, it does become portable.

That's right -- "the compiler is responsible for padding". So any code you write that assumes something like this will be unportable, reliant on compiler settings. Sure, on practically any compiler you can set this sort of thing, but it's an extra step involved. Your code doesn't compile out of the box on a new compiler.

And actually, I have once written something "unusual" that does something like this...

I was writing a small library for DirectInput w/ action feedback or whatever it's called. The program registered what keys it wanted to intercept and passed along a struct of bool values and the number of keys it has registered, that were set to true if key was pressed down and false if not.
Since the library had no idea of the contents of the struct, I used a raw memory approach. If key 4 was pressed, set beginning_of_struct + 4 to true, and so on.
Why did I do this? Why not an array or something? The approach to this is that the calling program can define the structure however they want as long as there's one member for each key. Then you can name the members whatever instead of a generic "bool key4;"

As far as I can see, it didn't help any. You'll have to explain a bit more, but I think you were using something like this

I'd guess you did that so that the mystery members could be named whatever the user wanted, right? Well, it still restricts the user to a data type that could fit into 4 bytes (or whatever the padding is).

Plus, if you just wanted custom names, then you should probably be using an interface to access the data. Abstract away the names.

Or if you really really wanted to do it, then you could have done something like this:

In other words, use the preprocessor to map some custom name to whatever the real name is. I've seen this done before. And while it's not the best programming practise, I would certainly consider it better than code that relies on fixed structure padding.

[edit] Another alternative would be to use unions to define custom names, possibly in conjunction with the preprocessor or whatever.

"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

That's right -- "the compiler is responsible for padding". So any code you write that assumes something like this will be unportable, reliant on compiler settings. Sure, on practically any compiler you can set this sort of thing, but it's an extra step involved. Your code doesn't compile out of the box on a new compiler.

But there should also be a way to force padding by a pragma. Though I'm not sure such a pragma exists on all compilers, or even if it's part of the standard.
But then again, many project modify compiler options and requires them to be changed to compile so setting padding in those projects isn't that much of a problem, but I do agree that it isn't usual practice and might be avoided.

And there you go, showing how appropriate it sometimes can be. Of course it's also possible to declare a struct with one bool array, it's just a matter of preferance.
But your other solution - to pass a struct and then copy it would be a waste of memory and time IMO, since I don't like copying memory when possible. Also, passing a predefined struct, you'd have to have a dynamically created array in it since the amount of keys can vary.
So either we use a pointer and new or we could use a class like CArray or something.

But there should also be a way to force padding by a pragma. Though I'm not sure such a pragma exists on all compilers, or even if it's part of the standard.
But then again, many project modify compiler options and requires them to be changed to compile so setting padding in those projects isn't that much of a problem, but I do agree that it isn't usual practice and might be avoided.

#pragma is, by definition, compiler-specific. I don't think there are many, if any, #pragmas that are defined by the standard, and structure padding certainly isn't one of them.

But your other solution - to pass a struct and then copy it would be a waste of memory and time IMO, since I don't like copying memory when possible.

Use the cast version, then. Unless you think that looks ugly, in which case use this.

"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

I mean, come on. There are so many ways to do it. You shouldn't need to use undefined structure behaviour to get it done.

Yes, I suppose it's possible, but it still relies on the same trick: memory manipulation.
Thinking on it, I believe it's possible with another approach, such as a map.
But the point is to show it's possible to interate through member variables in a struct without using the member names.

... so how is the original user, who defines their own structure, supposed to go about things? Do they dynamically create a different structure definition depending on which members they want to use?

They create on struct and use it. Because you only register what keys you want to capture once. Your app creates a struct like you want it to look like, with one member for each key. It's a dynamic structure to the library. Knowing how many keys there are, it can fill out the struct for you.
(Did that make sense?)

Yes, I suppose it's possible, but it still relies on the same trick: memory manipulation.

But in this case, as long as the members of the structure are of the same type, it's reasonably well defined memory manipulation.

Thinking on it, I believe it's possible with another approach, such as a map.

Sure, but that's going to kill your efficiency pretty quickly. Copying a structure would take a fraction of effort. (You'd have to store the names of the structure members as strings or at the very least enumerated values of a sort . . . .)

Unless you don't mean a standard std::map. But in any case you'd need some sort of lookup system.

Actually, the best way that I can think of to implement a lookup system of this sort would be to use something like this.

But the point is to show it's possible to interate through member variables in a struct without using the member names.

Sure, it's possible. But I'm saying that it's an exceedingly bad idea almost all of the time.

They create on struct and use it. Because you only register what keys you want to capture once. Your app creates a struct like you want it to look like, with one member for each key. It's a dynamic structure to the library. Knowing how many keys there are, it can fill out the struct for you.
(Did that make sense?)

Not really. It sounds like you have, say, 256 keys, and the user says "I want to handle 65, 66, and 32."

[edit] In other words, here's why I think you shouldn't use integral offsets from the beginning of a structure to allow the user to name the members of the structure however they like.

The user probably won't mind using your names, as long as you pick them well.

If they want to use their own names, they can copy their own structure;

or, if they're concerned about memory efficiency, use #defines, or references.

[/edit]

Last edited by dwks; 10-24-2007 at 01:13 PM.

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

Sure, but that's going to kill your efficiency pretty quickly. Copying a structure would take a fraction of effort. (You'd have to store the names of the structure members as strings or at the very least enumerated values of a sort . . . .)

Unless you don't mean a standard std::map. But in any case you'd need some sort of lookup system.

Yes, such as that. Though I tend to use CMap.

Actually, the best way that I can think of to implement a lookup system of this sort would be to use something like this.

Sure, it's possible. But I'm saying that it's an exceedingly bad idea almost all of the time.

Yes, bad it may be, but it's possible

Not really. It sounds like you have, say, 256 keys, and the user says "I want to handle 65, 66, and 32."...

That's not necessary since that's what action feedback is for. You tell DI what keys you want to capture and it reports only events when the those keys are pressed and released.
So a user can create a struct like

...But it will still work just fine.
The app can create the struct to look however it wants. It can even merge two or more keys into a WORD or an UINT. The library won't care and plot one byte for each key.
And the app can even change struct abruptly if it wants (like from KeyStruct1 to KeyStruct2) without negative effects.
And if an app doesn't want all that data captured all the time, it can just ignore those member variables which contain their state.

That's not necessary since that's what action feedback is for. You tell DI what keys you want to capture and it reports only events when the those keys are pressed and released.
So a user can create a struct like

...But it will still work just fine.
The app can create the struct to look however it wants. It can even merge two or more keys into a WORD or an UINT. The library won't care and plot one byte for each key.
And the app can even change struct abruptly if it wants (like from KeyStruct1 to KeyStruct2) without negative effects.
And if an app doesn't want all that data captured all the time, it can just ignore those member variables which contain their state.

See below.

But you can't rename the members, which was the point.

Why would you want to rename structure members anyway?

Here's what I think. You want to create something so that the user can name the members of their structure. You don't want to create references to the members or copy a structure or use a lookup table or one of the many other valid solutions. You want to let the user name their own structure members. Very well. What's wrong with this?

It lets the user create their own structure. It doesn't take much extra memory (one reference, which can probably be optimised away). It doesn't rely on undefined practises -- it's defined for any and all standards-compliant compilers. It doesn't use the preprocessor.

Its only drawback is that you can't access the members of the internal structure as an array. You could use this

Code:

struct internal {
bool _internal_data[2];
};

but I think that's just as bad as your code, assuming that there's no structure padding at all.

But wait a minute here. Why not just use an array in the first place?

Code:

bool array[2];

Then, if the user wants to use their own names, they can make up constants like ONE=0. This is quite a few advantages. It will use less memory, unless with you're structure you're using every possible byte and thus have in effect no padding. It's easy for you to handle. It's easy for the user to handle, with your names, constants, or their names.

If you need more data then you can stuff into an array, use a structure.

Please, tell me. Why would you be willing to risk portability to let the user use their own names? It's your library. If they don't like your names, they can deal with it, with #defines or structures or maps or references. And if you want to allow the user to create their own names, you can use these techniques yourself. There's no reason that I can see to use a possibly shady coding style when alternatives exist.

Besides, your method isn't perfect either. The user is restricted to the order of their variables.

The app can create the struct to look however it wants. It can even merge two or more keys into a WORD or an UINT. The library won't care and plot one byte for each key.

You can do this without involving structures.

Code:

char x = 1, y = 2;
short both = x | y << CHAR_BIT;

And you can't do it in your example. You know why? Because of structure padding. If you translate this

Code:

struct x {
small one, two;
};

to this

Code:

struct y {
large both;
};

then both has to contain x + x's-padding + y + y's-padding. And part of it will be undefined, 'cause you don't set every byte, do you? Just every fourth, or whatever. (Easily fixed with a memset, of course.)

If you're just setting a bunch of values of the same type, use an array. That's what they're for.

If I saw a library like yours, I'd think "What was this designer thinking?" It's just complicated, unreasonably so. But if I saw a library that stored keypresses in an array, I'd know exactly how to handle 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

I may be repeating myself, but... I did mention there may be other ways to do it. You've mentioned several. And very good ones, too. My initial spark argument was that it can be done, not about how to do it
As for the question of why doing it, it's because it will make the code more readable. That's the whole point! And also, to avoid thinking "WTF? What did data[6] do?"

Right, okay. It can be done. It might be a bad idea, it might be unportable, there might be better ways to do it -- but it can be done.

I don't think arrays would be less readable. You wouldn't use data[6], you'd use data[SDLK_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

I don't think arrays would be less readable. You wouldn't use data[6], you'd use data[SDLK_RIGHT].

Arrays with a generic name might be "unreadable" since you have no idea what data is stored in them
But you're right that you can sidestep the problem!
And remember, the reason why we don't name variables everywhere a, b, c, etc is because we want to know what they're used for so a fitting description is a good or else we may be come confused!

Right, so you say that "right" is more readable than 4. I agree. But there's no reason you can't use an enum or something to give it the name "right". If you do this, you still get all of the advantages of using an array -- little memory usage, ease of handling with standard functions like memmove(), iteration with a for loop if you choose.

In other words, you can let the user go "left, right, up, down", which might be more readable in many cases. But in others, using array[0] ... array[3] would be better, for loops or transferring all the data at once. Or whatever. If you use an array, the user can use either method (iteration or naming). If you use naming, they're stuck with it.

Your argument, of course, would be that you've designed it so that the user can use "int left, int right, int up" or "int array[3]" -- so they get to choose. It's just as good as using an array, because you can use an array if you want or names if you don't.

But that argument falls apart, because the only way you can declare an array in a structure and have it work is to take into account structure padding. For example,

Code:

struct everything {
long data[4];
};

with 4-byte padding and 4-byte longs. You're wasting memory. Plus you're not using the data type you were looking for.

Okay, so then do this.

Code:

struct omnibus {
struct data {
bool x;
} array[4];
};

But you're still wasting memory.

So I think this: an array is better than a structure, in general, if you could use either -- for these reasons:

Arrays might use less memory, and certainly not more.

A structure might involve undefined structure padding issues.

You can iterate over arrays, while to do this with a structure you need an array anyway.

You can access array elements by name easily, with defined constants or maps. It's certainly not much harder than using structure members.

Arrays are more traditional for this sort of thing. You have a bunch of variables of the same type. What do you use? An array. So this is what other programmers would expect.

At least in this case.

I suppose it all comes down to this. How badly do you want to use structure.member as opposed to array[element]?

"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

I don't care! My argument has finished... and all it was was that it was possible to enumerate members of a structure without knowing their names or even if they have different names in a loop, which we've also concluded is bad and unsafe.
If anything, I'd use a map. Probably map string to pointer, with each "key name" pointing to a local (or global, or whatever) variable.

Right, argument over. Oh well. I haven't had one like that for a while, it was interesting.

If anything, I'd use a map. Probably map string to pointer, with each "key name" pointing to a local (or global, or whatever) variable.

But that would be inefficient compared to <forcibly stops typing>

A map has other advantages over other methods. For example, the keys can be dynamically generated, by reading from a file for example.

What you use depends on what you want to do. And how portable you want your program to be.

[edit] 5,300th post! [/edit]

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