Structure sizes

I think most of us here agree with that.

I’m looking at this out of context, but this doesn’t sound very good in general.

I’ve seen this done quite elegantly.

typedef unsigned var1;
#define PVAR1(ptr) (var1 *) ( ((char *) ptr+VAR1_OFFSET)

read(fd,RECORD_SIZE,buffer);
x = *PVAR1(buffer);

Or something like this.

Micro,

Your other option if your worried about packing the structures is to do what I did with my case which is define 2 identical structs. One that is packed to read the data. The other that isn’t that I do real work with.

#pragma pack(push, 1)
struct packedstruct{
char somefield[25];
short firstshort;
short anothershort;
unsigned short nowunsignedshort;
unsigned int wealsohavethisinint;
unsigned int therearemore;
char onemorearray[120];
}
#pragma pack(pop)

struct somestruct{
char somefield[25];
short firstshort;
short anothershort;
unsigned short nowunsignedshort;
unsigned int wealsohavethisinint;
unsigned int therearemore;
char onemorearray[120];
}

So in my code, I use the packed struct to read data (in your case from a file). Then I immediately copy it into a non-packed struct and use that the rest of the time. In C++ land, it’s trivial to just create a simple copy constructor in the 2nd struct that takes the 1st struct as an argument and does individual copies on all the members of the struct (In C you’ll have to create a function).

This means you can continue to take advantage of speed and don’t have to worry about packing everything in your system or having size issues. If you write back to these same files, you just write using the same packed structure.

Tim

Yuck!

“Macros like this have so many drawbacks, just thinking about them is painful.” --Scott Meyers, Effective C++

“Avoid function macros.” --Kernighan & Pike, The Practice of Programming

“Avoid macros… Macros ignore scope, ignore the type system, ignore all other language features and rules, and hijack the symbols they #define for the remainer of a file… writing even remotely proper macros [is] a black art whose mastery is as unrewarding as it is tedious.” --Sutter and Alexandrescu, C++ Coding Standards

“The first rule about macros is: Don’t use them unless you have to. Almost every macro demonstrates a falw in the programming language, in the program, or in the programmer.” --Bjarne Stroustrup, The C++ Programming Language

Here’s a function version:
const int VAR1_OFFSET = 0x1234;
int * PVAR1(char *ptr){
return (int *) (ptr+VAR1_OFFSET);
}

read(fd,RECORD_SIZE,buffer);
x = *PVAR1(buffer);

Personally, I think the function is easier to read. And you get some type safety from the return type.

-James Ingraham
Sage Automation, Inc.

Well this reply makes it clear that we are coming at this from different places.
We’re discussing how to replace code that fails because of an alignment error, with something portable.
My first priority is efficiency, which admittedly becomes less and less important as Moore’s law forges forward, and readability second.
Your priority seems to be an esthetic that I don’t really understand. That your three quotes are in reference to C++ may indicate why. To replace an inline assignment with a subroutine call makes my bones chill, given that there is an alternative. Of course C++ proscribes this solution to the question of how to access and modify a class member.

If the problem with my suggestion was just MACROS, then you could replace my code with this:

char buffer[RECORD_SIZE];
struct
{
char var1;
int var2;
float var3;

} record;

read(fd,RECORD_SIZE,buffer);
record.var1 = *(char *) ((char *) buffer+VAR1_OFFSET);
record.var2 = *(int *) ((char *) buffer+VAR2_OFFSET);
record.var3 = *(float *) ((char *) buffer+VAR3_OFFSET);

No macros and very ugly.

I’m really not trying to pick a fight here. I don’t think that there is just one “right” way to code things,
although I would agree that circumstances often dictate one in context.

I may overdone it a bit by n-thousand, but it will be quite a lot. I´ll try the attribute-flag now (this will take some days i guess ;P)

-fpack_struct worked fine till hmm, errr, something went wrong and the app just vanished ^^
Hell, i think the best way is really with the attribute within #ifdef/#endif.

Micro,

I sort of figured the -fpack_struct would cause a failure someplace, especially if you use optimized builds.

I’m not sure why the attribute method will take you days. Unless you mean days of testing. It is only 2 lines of code. The #ifdef and #endif. You only need this where you declare the structure, not everyplace you use it.

KGB

but it is about 100+ structures. Intercommunication with ppc, custom cards, a lot of structures saved to files, communicate with older applications, etc.
This will take some time. First to find where to put these lines and second to test if it works then. (and yes, there are about 30 different cards that needs to be supported)

I wonder how you get away with unaligned structures on PPC. Also, do you “write()” a binary structure into file, and have PPC reading it? There is Endian issue in there…

I’m in 100% agreement so far.

I would normally cringe at that statement, but certainly if you’re trying to cut costs down on shipping 100,000 units a month it makes sense. However, I don’t think you are correct that the macro is any faster, thanks to modern optimizing compilers. And debugging is WAY easier if you’ve used functions and consts instead of #defines. For better or worse, that’s not something you can conditionally compile for debug or production builds.

Two programmers with a different views on style? I don’t believe it! :wink: It is true that my “embedded” systems have comparitively massive amounts of horsepower, allowing me to do things like use C++.

Ever benchmark this? I bet with optimization on you won’t see a statistically significant difference.

Well, C++ really will introduce overhead if you aren’t VERY careful about how you code your classes. Again, my systems don’t care, but I wouldn’t recommend class methods over functions on typical embedded systems.

Even I would pick the macros over that.

Darn. I was spoiling for a good fight.

Of course there’s a right way! The open curly brace goes on the line with the if statement, and any who disagree shall burn in eternal torment!!!

Note the three exclamation points. I must be right if I’m willing to put three exclamation points, right?

:slight_smile:

-James Ingraham
Sage Automation, Inc.

First of all there is no such thing as “burn in eternal torment” which puts a serious dent on your credibility. Had you used the word “Hell” then credibility would have gone down the drain big time. For that reason I’m not willing to take your opinion about curly brace position seriously. You will have to do better then that.

Careful James, use any more than three and they have to ship you off to demented villian prison… ;-)

On the topic of James’ function accessor, putting a simple ‘inline’ attribute on the accessor will resolve Mitch’s problems, I think. It should be noted that C++ inlines these small functions by default when optimising.

Well we certainly do come from different era’s. I’m not trying to save a dime. I don’t try to hand optomize assembler either (well almost never). If I actually run into a situation where debugging is made easier by putting in a subroutine, I put in a subroutine. I love some of the “cool” stuff that C++ provides over ‘C’. My main beef is not that it is less efficient, no doubt it is more so in some cases, but that it is often hard to know what it is doing at the assembler level, at least without going in and looking at the generated code. I fully admit that this is rarely important anymore.
Of course we both are bothering to use a “real-time” OS. Maybe you are not concerned about this feature?
And I’m not saying that the two are incompatible, 1) the need for a RT OS, 2) minimal concern over generated code.
But surely if your embedded system needs 1) you have some concerns about time.

At one time I had to bench mark the difference between “test” and “cmp”, so yes. Have I done it
lately, no. We are really squeezing this question into a tight corner (which is fine). I hope you don’t think I would
use a goto because it doesn’t require a push of the return address into the stack. I do fail to see what is wrong with using a macro to avoid having to put a single line of code into a subroutine. I also recognize the fact that sometimes my esthetic goes out the window, like when I program in php.

I really hope I’m reading the right amount of sarcasm into this statement. I used to write code this way for years.
I finally figured out that my use of the practice was historically based on BASIC, as in:

IF A=5 THEN

So I don’t do that anymore. I feel my feet warming up as we speak.

I thought you had to type in all CAPS to be absolutely right. But then again, I didn’t type this last statement in all caps, so I might not be right, right?

xtang:
It may be true that using aligned structures for communicating with the PPC would be easier, but i am not the guy programming the PPC Code.
Also there is a algorithm already implemented in the ppc-code Big->Little for a long time. I guess it would be more harmful starting changing
the PPC code now too.

But back to topic: -fpack_struct shouldn´t do any problems with library structrues, since they are declared in the library, shouldn´t it?
(And yes i still run -fpack-struct, since i gave up after 2 days searching for structures ^^)

Just in case, I was being sarcastic, no disrespect intended, you can put the curly brace where ever you set fit, lol!

Sorry to roll up this topic again, but i´d like to put out what the conclusion was now:

First of all, there is a pretty easy example when -fpack-struct is going to exploit.
Just try to compile something with PtFileSel… the PtFileSelInfoT Structure will SIGSEGV on member fullname.

The end now was, sitting 2 weeks in front of the Monitor checking every appearance of the word “struct” an on structure-declarations putting the attribute ((packed)) to it.
But this was done by:
#ifdef QNXNTO
#define STRUCT struct attribute ((packed))
#endif
#ifdef QNX4
#define STRUCT struct
#endif

Now we just need to replace struct for STRUCT on every f… needed line, and yes, i checked up with grep…|wc -l , there were 5200 structs …
Hell of a time, i already started dreaming about structs…

Micro,

Wow. That seems like an awful lot of work to solve something that on the surface doesn’t look anywhere near that complex.

I mentioned in an early post we do something very similar to what you want to do. What I ended up doing was the following:

#pragma pack(push, 1)
typedef struct
{
    int a;
    char b;
    float c;
} FooIO;
#pragma pack(pop)

typedef struct
{
    int a;
    char b;
    float c;
} Foo;

void copyIt(Foo *f, FooIO *fTemp)
{
    f->a = fTemp->a;
    f->b = fTemp->b;
    f->c = fTemp->c;
}

Then in the code that reads/writes from the files you use the FooIO like so

FooIO fTemp;
Foo f
while (fgets(&fTemp, sizeof(FooIO), fp) != NULL)
{
    copyIt(&f, &fTemp);
}

This assumes that your entire code base is already using Foo as the struct to manipulate the data. Thus the only time you worry about the byte alignment is when you read/write from the file.

For us, we aren’t trying to read/write in realtime so the small penalty paid for using copyIt() isn’t an issue. The upside is nothing else has to change code wise because it doesn’t matter how much space Foo uses up under QNX4/QNX6 because it’s always stored/read correctly.

Tim