Apologize if you see this post in other usergroups.
I have met a strange problem while I use GCC to compile a very simple
src:
int main()
{
short p[10];
int *pp = (int*)&p[1];
*pp = 1;
return 1;
}
Whe the src is compiled with GCC gcc (GCC) 3.4.3
(csl-sol210-3_4-branch+sol_rpath) and 3.3.2
), it will generate core dump for SIGBUS.
I know this is due to unaligned memory access for SPARC.
So I add the type attribute for the short array;
short p[10] __attribute__ ((aligned (4)));
But it doesn't take effect for the memory alignment and still generates
a coredump.
The compile command is also very simple: /usr/sfw/bin/gcc align.c
Does anybody know how to make this piece of code execute sucessfully
with changing src.
Your solution and comments are highly appreciated.
Regards,
Adam
Adam,
this code generates a SIGBUS for a reason...it contains
an error. Correct the error, and the code will run.
Any other attempt to make this code "work somehow"
will still leave a chance for undefined behaviour.
Rainer
It should. You are acessing the second element of p and if the first
is 4-byte aligned, the second will be 2-byte aligned, hence the
SIGBUS.
If I am correct (I cannot test this ;-), using __attribute__
and int *pp = (int *)p may work (eventually depending on the compiler
settings wrt 'strict aliasing').
This code does not 'generate SIGBUS'. An alignment trap 'happens' on the
CPU and the kernel fault handler for this trap posts a SIGBUS to the
offending process.
> it contains an error.
It contains something whose behaviour is undefined according to
C99. The compiler that was used doesn't even support C99 (fully).
> Correct the error, and the code will run.
I think the intent was to understand what was going on in the compiled
machine code.
> Any other attempt to make this code "work somehow" will still leave
> a chance for undefined behaviour.
The behavious is (and will remain) undefined as of C99. But this does
not mean something specific, but the absence of anything specific --
the ISO-C99 norms does not tell you how the compiled program is
supposed to behave and 'imposes no requirements' on a conforming
implementation regarding its treatment. And that's really
all. Everything else is up to conforming implementations.
what do you really want to say?
Hi Rainer,
Thanks for your detail explanations.
Yes I can use integer pointer to point to the short array directly as
you said. But I find the alignment for this short array isn't defined
by this align attribute.
Here is another good example:
main()
{
printf("---short to int * -------\n");
short sh1 __attribute__ ((aligned(4))) = 0;
int * psh1 = (int *)(&sh1);
printf("sh1 address is %x, psh1 point to %x\n", &sh1, psh1);
*psh1 = 1;
return 1;
}
This code output is :
sh1 address is ffbffdde, psh1 point to ffbffdde
Bus Error(core dumped)
I find this aligned attribute doesn't change the varaible address in
the memory. Do you have any idea about this.
A portable solution which works with any compiler is to use memcpy:
int main()
{
short p[10];
int i = 1;
memcpy(p + 1, &i, sizeof i);
return 0;
}
union u mu;
int *pp = (int *)&mu.p[0];
However, memcpy() is more elegant in most of the cases.
--
WYCIWYG - what you C is what you get
[...]
>> It should. You are acessing the second element of p and if the first
>> is 4-byte aligned, the second will be 2-byte aligned, hence the
>> SIGBUS.
>>
>> If I am correct (I cannot test this ;-), using __attribute__
>> and int *pp = (int *)p may work (eventually depending on the compiler
>> settings wrt 'strict aliasing').
>
> A portable solution which works with any compiler is to use memcpy:
As I have written in another post: I think the point is not how to
make this (useless) piece of code work, but 'what is going on here'.
According to the attribute-documentation, the variable should be
aligned on a 4-byte boundary and the code just demonstrates that it
isn't. The documentation (for gcc 3.3.5) contains the following text:
Note that the effectiveness of `aligned' attributes may be
limited by inherent limitations in your linker. On many
systems, the linker is only able to arrange for variables to
be aligned up to a certain maximum alignment. (For some
linkers, the maximum supported alignment may be very very
small.)
This apparently implies that only objects visible to the linker can be
aligned this way and that the attribute is silently ignored for
automatic variables. If you happen to have code that uses this
attribute for some reason (like I), that is certainly something worth
knowing.
Read the posting.
> "Maxim Yegorushkin" <maxim.ye...@gmail.com> writes:
> > Rainer Weikusat wrote:
>
> [...]
>
> >> It should. You are acessing the second element of p and if the first
> >> is 4-byte aligned, the second will be 2-byte aligned, hence the
> >> SIGBUS.
> >>
> >> If I am correct (I cannot test this ;-), using __attribute__
> >> and int *pp = (int *)p may work (eventually depending on the compiler
> >> settings wrt 'strict aliasing').
> >
> > A portable solution which works with any compiler is to use memcpy:
>
> As I have written in another post: I think the point is not how to
> make this (useless) piece of code work, but 'what is going on here'.
What happens is that sparc processor can not deal in hardware with
unaligned data and generates a trap as you wrote. x86 can cope with
unaligned data with some performance degradation, an it has a mode when
it generates a trap for unaligned access as sparc does.
> According to the attribute-documentation, the variable should be
> aligned on a 4-byte boundary and the code just demonstrates that it
> isn't. The documentation (for gcc 3.3.5) contains the following text:
Sorry, I can not understand how aligned attribute could be of use here.
It may align the beginning of the object on a certain boundary, array
being the object in this case. Arrays are stored contiguously in C/C++,
so no matter how you align the beginning of it, individual array
elements will be aligned using their own natural of forced alignment.
The natural alignment for a fundamental T is sizeof(T) and if
sizeof(short) != sizeof(int) as it is here, you are still doing
unaligned access.
<side note>
At some point in time, I need to determine where all these identically
behaving people come from, with whom meaninful communiction
is impossible, because they never listen again after having formed a
wrong initial opinion. I suspect this to be related to math ...
</>
That was the part everybody understood. But the access should not have
been misaligned, because, according to the compiler documentation, the
variable should have been aligned on a 4-byte boundary, but it isn't.
[...]
>> According to the attribute-documentation, the variable should be
>> aligned on a 4-byte boundary and the code just demonstrates that it
>> isn't. The documentation (for gcc 3.3.5) contains the following text:
>
> Sorry, I can not understand how aligned attribute could be of use here.
> It may align the beginning of the object on a certain boundary, array
> being the object in this case. Arrays are stored contiguously in C/C++,
> so no matter how you align the beginning of it, individual array
> elements will be aligned using their own natural of forced alignment.
> The natural alignment for a fundamental T is sizeof(T) and if
> sizeof(short) != sizeof(int) as it is here, you are still doing
> unaligned access.
That is another thing that (with a high probability) nobody ever
doubted.
#include <stdio.h>
short y __attribute__ ((aligned (16))) = 0;
int main(void)
{
short x __attribute__ ((aligned (16))) = 0;
printf("%p\t%p\n", &y, &x);
return 0;
}
> "Maxim Yegorushkin" <maxim.ye...@gmail.com> writes:
> > Rainer Weikusat wrote:
>
> [...]
>
> >> It should. You are acessing the second element of p and if the
> >> first is 4-byte aligned, the second will be 2-byte aligned, hence
> >> the SIGBUS.
> >>
> >> If I am correct (I cannot test this ;-), using __attribute__
> >> and int *pp = (int *)p may work (eventually depending on the
> >> compiler settings wrt 'strict aliasing').
> >
> > A portable solution which works with any compiler is to use memcpy:
>
> As I have written in another post: I think the point is not how to
> make this (useless) piece of code work, but 'what is going on here'.
> According to the attribute-documentation, the variable should be
> aligned on a 4-byte boundary and the code just demonstrates that it
> isn't.
short p[10] __attribute__ ((aligned (4)));
The question is whether the array is aligned, or each member. I would
think that writing the following should ensure that each member of the
array is aligned:
short p __attribute__ ((aligned (4)))[10];
assuming, of course, that this syntax is supported by GCC (I don't
know, and I don't want to find out :-).
> The documentation (for gcc 3.3.5) contains the following text:
>
> Note that the effectiveness of `aligned' attributes may be
> limited by inherent limitations in your linker. On many
> systems, the linker is only able to arrange for variables to
> be aligned up to a certain maximum alignment. (For some
> linkers, the maximum supported alignment may be very very
> small.)
>
> This apparently implies that only objects visible to the linker can be
> aligned this way and that the attribute is silently ignored for
> automatic variables. If you happen to have code that uses this
> attribute for some reason (like I), that is certainly something worth
> knowing.
Automatic variables should always be aligned because the linker is not
involved at all - they get created on the stack, and hence are
under complete control of the compiler.
The link editor resolves the address specifications emitted by the
compiler, and it might have limitations the compiler isn't aware of.
Take care,
--
Stefaan A Eeckels
--
When the need is strong, there are those who will believe anything.
-- Arnold Lobel
[...]
>> As I have written in another post: I think the point is not how to
>> make this (useless) piece of code work, but 'what is going on here'.
>> According to the attribute-documentation, the variable should be
>> aligned on a 4-byte boundary and the code just demonstrates that it
>> isn't.
>
> short p[10] __attribute__ ((aligned (4)));
>
> The question is whether the array is aligned, or each member.
This may be considered questionable, but the compiler documentation
says the variable should be aligned and the C-standard would not allow
something else, anyway.
[...]
>> The documentation (for gcc 3.3.5) contains the following text:
>>
>> Note that the effectiveness of `aligned' attributes may be
>> limited by inherent limitations in your linker. On many
>> systems, the linker is only able to arrange for variables to
>> be aligned up to a certain maximum alignment. (For some
>> linkers, the maximum supported alignment may be very very
>> small.)
>>
>> This apparently implies that only objects visible to the linker can be
>> aligned this way and that the attribute is silently ignored for
>> automatic variables. If you happen to have code that uses this
>> attribute for some reason (like I), that is certainly something worth
>> knowing.
>
> Automatic variables should always be aligned because the linker is not
> involved at all
That's certainly a sensible theory, but the facts are that the
attribute is ignored for automatic variables and the documentation
snippet I cited above hints at the possibility that this may be
because the linker is not involved.
> <side note>
> At some point in time, I need to determine where all these identically
> behaving people come from, with whom meaninful communiction
> is impossible, because they never listen again after having formed a
> wrong initial opinion. I suspect this to be related to math ...
> </>
If you can't communicate meaningfully with "all these people", maybe,
just maybe, you should start wondering whether the problem could be...
you :-)
--
Stefaan A Eeckels
--
Q: If ignorance is bliss, why aren't there more happy people in the
world? A: Because they don't know they're ignorant.
> Stefaan A Eeckels <hoen...@ecc.lu> writes:
> > On Tue, 05 Dec 2006 11:24:19 +0100
> > Rainer Weikusat <rainer....@sncag.com> wrote:
>
> [...]
>
> >> As I have written in another post: I think the point is not how to
> >> make this (useless) piece of code work, but 'what is going on here'.
> >> According to the attribute-documentation, the variable should be
> >> aligned on a 4-byte boundary and the code just demonstrates that it
> >> isn't.
> >
> > short p[10] __attribute__ ((aligned (4)));
> >
> > The question is whether the array is aligned, or each member.
The array, not members.
> >> The documentation (for gcc 3.3.5) contains the following text:
> >>
> >> Note that the effectiveness of `aligned' attributes may be
> >> limited by inherent limitations in your linker. On many
> >> systems, the linker is only able to arrange for variables to
> >> be aligned up to a certain maximum alignment. (For some
> >> linkers, the maximum supported alignment may be very very
> >> small.)
> >>
> >> This apparently implies that only objects visible to the linker can be
> >> aligned this way and that the attribute is silently ignored for
> >> automatic variables. If you happen to have code that uses this
> >> attribute for some reason (like I), that is certainly something worth
> >> knowing.
> >
> > Automatic variables should always be aligned because the linker is not
> > involved at all
>
> That's certainly a sensible theory, but the facts are that the
> attribute is ignored for automatic variables and the documentation
> snippet I cited above hints at the possibility that this may be
> because the linker is not involved.
Stack variables are aligned using sole "and %rsp, alignment"
instruction when the stack grows down. The instruction does not refer
to any symbols, so that the linker has nothing to do with it.
If a certain set of people tends to consistently ignore facts (like in
this thread), it is diffcult to communicate with them and that is
their fault.
[...]
>> >> This apparently implies that only objects visible to the linker can be
>> >> aligned this way and that the attribute is silently ignored for
>> >> automatic variables. If you happen to have code that uses this
>> >> attribute for some reason (like I), that is certainly something worth
>> >> knowing.
>> >
>> > Automatic variables should always be aligned because the linker is not
>> > involved at all
>>
>> That's certainly a sensible theory, but the facts are that the
>> attribute is ignored for automatic variables and the documentation
>> snippet I cited above hints at the possibility that this may be
>> because the linker is not involved.
>
> Stack variables are aligned using sole "and %rsp, alignment"
> instruction when the stack grows down. The instruction does not refer
> to any symbols, so that the linker has nothing to do with it.
Your second sentence is a repetition of the last line of my text.
You do not address the attribute issue at all. Your first sentence is
another instance of 'stating the obvious'.
Would you perhaps enlighten me what the purpose of your text is
supposed to be?
Actually I also read the GCC's type attribute alignment doc, but I
didn't get its meaning.
Thanks for your reply and kind explanations.
After I make this variable as global variable, it can be alignned with
type attribute alignment.
You are pefectly right. My post is just make integer pointer to point
to short value to test type attribute alignment. Thanks for your help.
Hi all,
typedef short align_sh __attribute__ ((aligned(4)));
align_sh garray1[10];
or
short garray1[10] __attribute__ ((aligned(4))) ;
The align just only happens to the array
short garray1 __attribute__ ((aligned(4))) [10] ; //can't be compiled
It seems that we can't aliagn each array's member.
Anyway, this is just a test for the C programm not for the practical
coding.
Thanks for your kind help. Now I know how GCC works for type attribute
alignment.
> "Maxim Yegorushkin" <maxim.ye...@gmail.com> writes:
> > Rainer Weikusat wrote:
>
> [...]
>
> >> >> This apparently implies that only objects visible to the linker can be
> >> >> aligned this way and that the attribute is silently ignored for
> >> >> automatic variables. If you happen to have code that uses this
> >> >> attribute for some reason (like I), that is certainly something worth
> >> >> knowing.
> >> >
> >> > Automatic variables should always be aligned because the linker is not
> >> > involved at all
> >>
> >> That's certainly a sensible theory, but the facts are that the
> >> attribute is ignored for automatic variables and the documentation
> >> snippet I cited above hints at the possibility that this may be
> >> because the linker is not involved.
> >
> > Stack variables are aligned using sole "and %rsp, alignment"
> > instruction when the stack grows down. The instruction does not refer
> > to any symbols, so that the linker has nothing to do with it.
>
> Your second sentence is a repetition of the last line of my text.
It is not.
> You do not address the attribute issue at all. Your first sentence is
> another instance of 'stating the obvious'.
>
> Would you perhaps enlighten me what the purpose of your text is
> supposed to be?
You wrote:
... the facts are that the attribute is ignored for automatic variables
and the documentation snippet I cited above hints at the possibility
that this may be because the linker is not involved...
My answer in other words was:
It's not because the linker is not involved. A compiler is able to
align automatic variables on its own and ir does so, it does not need
any linker help for this task at all.
[...]
>> You do not address the attribute issue at all. Your first sentence is
>> another instance of 'stating the obvious'.
>>
>> Would you perhaps enlighten me what the purpose of your text is
>> supposed to be?
>
> You wrote:
>
> ... the facts are that the attribute is ignored for automatic variables
> and the documentation snippet I cited above hints at the possibility
> that this may be because the linker is not involved...
>
> My answer in other words was:
>
> It's not because the linker is not involved. A compiler is able to
> align automatic variables on its own and ir does so, it does not need
> any linker help for this task at all.
The question was not what you believe the compiler could do, but what
it actually does. This particular compiler overrides user alignment
requests for automatic variables (check the source) and implements
user alignment for variables with static storage duration by emitting
.align directives into the generated assembly code.
That was basically what I already guessed, because they way the
documentation mentioned linker limitations suggested that every
user request for a specific alignment would be processed by the linker,
and, BECAUSE THE LINKER KNOWS NOTHING ABOUT AUTOMATIC VARIABLES (and neither
does the assembler), that cannot be if such requests are
honored for automatic variables.
And please no more 'explanations' of trivia regarding basic
development tools ...
> That was basically what I already guessed, because they way the
> documentation mentioned linker limitations suggested that every
> user request for a specific alignment would be processed by the linker,
> and, BECAUSE THE LINKER KNOWS NOTHING ABOUT AUTOMATIC VARIABLES (and neither
> does the assembler), that cannot be if such requests are
> honored for automatic variables.
If that's what the documentation meant, it said it in a very poor way.
The way it's written suggests that the compiler will try to honor
alignment directives, but when the linker is involved it will be limited
to the capabilities of the linker. Since the linker is not involved in
automatic variables, the linker's limitations shouldn't be a factor.
--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
We also can make union as array so that each memeber of the array will
be aligned like integer.
True.
The representation of such array in memory will be an array of int's
rather than short's, i.e. an array of the largest member in the union.
You could as well declare your array as an array of int's to achieve
the very same effect.