I've got a problem where Pelles is putting static variables that should be aligned on at least 4 byte boundaries into odd memory addresses. I've got one of the cases whittled down down quite a bit, and it's interesting.
// I include these even though I don't use them all, since that is
// what was included in the program that had alignment problems.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct _inputArgntfsState
{
double sum;
int actionType;
bool writeDoesntClear;
bool forReads;
bool forWrites;
bool changedInfo;
int convertedStreet;
} inputArgntfsState, IASS, *PIASS;
bool k = 0;
IASS x = {0}; // Makes us come out an an odd address.
//IASS x; // Will come out at the correct 4 byte address.
int main(int agrc, char **argv)
{
printf( "sizeof(k) = %d, &k = 0x%X,\n", sizeof(k), &k );
printf( "sizeof(x) = %d, &x = 0x%X,\n", sizeof(x), &x );
return 0;
}
Run the program and x is at an odd address (at least on my Intel WinXp machine). Comment out line 21 and uncomment out line 22 and x is at a nice 4 byte boundary. Now, admittedly line 21 does not technically fill out the entire structure on a per member basis, but that should not cause an alignment issue.
BTW, #pragma pack has no effect.
Thanks
Jack
Note that one may ponder whether or not the structure should be aligned on an 8 byte boundary versus 4 because of the double, but that's a different question.
The odd address is generated only if you choose optimization for space or none. Using optimization for speed generates correct alignment.
This could be considered correct choosing the optimization for space because packing variables reduce the memory space used. Seems a little bit more strange when no optimization are choosed.
Anyway a pragma for alignement could be desirable, considering that the pragma pack works only for structure members alignment.
As a workaround you can change the optimization method if consistent with the scope of your software, or use the pragma optimize to align locally in the sensible software parts.
You can post for a feature request that seems a rasonable improvement.
Yes, the general idea is that when optimizing for space, the smallest executable should be generated. Tight packing of global variables, without padding/alignment bytes, is one attempt at shaving off some bytes.
I can't see anything wrong with this, but since the question of alignment comes up over and over and over again, perhaps better to always align global data. I don't care myself, since I always optimize for speed. I'm not sure that adding yet another Pelles C-specific pragma is the best/most helpful approach... Probably better to be consistent, and always align, even though it may waste (a lot of) extra bytes for some programs...
Quote from: Pelle on April 04, 2007, 03:23:44 PM
Yes, the general idea is that when optimizing for space, the smallest executable should be generated. Tight packing of global variables, without padding/alignment bytes, is one attempt at shaving off some bytes.
It also happens with no optimization though.
My personal preference would be always align.
John
Yes, you're right. It is the optimization level. I use "None" for debugging, maximize speed for production code.
I think if one chooses minimize space, then it's understandable to try to squeeze things down. But for optimize none, I'd like it to go with default alignment values (e.g. 4 byte aligned int's, etc.).
Thanks
Jack
I'm not convinced that no optimization *must* mean alignment. But in the name of general consistency, I think it's best to *always* align globals. It's not terribly hard to rearrange globals (and members) to avoid most padding bytes, and if people don't care about that, they probably don't care about the extra padding bytes either.
I vote for always aligning globals...
I agree.
Anyway with no optimazition I think it's better to let a more natural access of the processor to the memory. Normally a 16/32 bits processor suffers extra bus cycles to access odd address memory.
That's settled then! :)
John
I still have a techie question. Why did
IASS x = {0};
generate odd alignment and yet the plain
IASS x;
generate even alignment? Does it have to do with the fact that the two are going to different memory regions, and that the second case just happens to align (in this case) to an even boundary?
Thanks
Jack
IASS x;
This will end up in the BSS section as a 'communal' symbol. For this case, more than one (compiled) module may define the same variable, and the linker will use the largest size (if, for some reason, the modules don't agree about the type).
I don't have all the details at the top of my head, but I think this makes it hard to enforce a certain alignment (not sure enough information is available, for example...)
Quote from: Pelle on April 04, 2007, 03:23:44 PM
I can't see anything wrong with this
There's a lot wrong with this. Optimizing for space has everything to do with code generation and nothing to do with data generation. It's your job to make the code smaller. It's my job to make the data smaller. The best you can do is to rearrange the data to minimize the pad bytes.
Where I found the alignment problem is with passing UNICODE strings to the UNICODE Registry functions. Odd addressed strings cause the functions to fail every time.
severach, your post could be seen as as rude, arrogant and unnecessary, is that what you intended?
John