You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@stdcxx.apache.org by Martin Sebor <se...@roguewave.com> on 2008/06/25 01:55:33 UTC

question about aligned_storage

While looking at the hoops we jump through to implement aligned_storage
I recalled the gcc __attribute__ (aligned (N)). Is there any to use it
to simplify the implementation for gcc?

See http://tinyurl.com/5kmvdy for reference.

Martin


RE: question about aligned_storage

Posted by Travis Vitek <Tr...@roguewave.com>.
 

Martin Sebor wrote:
>Martin Sebor wrote:
>> Travis Vitek wrote:
>[...]
>>>>> The draft shows a 'typical implementation' of 
>aligned_storage that 
>>>>> uses the new alignas keyword,
>>>>> but alignas doesn't appear to be supported
>>>>> anywhere.
>>>> That's probably because they didn't want to favor any existing
>>>> implementation over others.
>>>
>>> I don't see this as a problem with the standard not wanting 
>to favor one
>>> implementation over another, it is a problem because no current
>>> implementation supports the new keyword.
>> 
>> That might have been the point: use a made up keyword that doesn't
>> exist on any implementation so as not to suggest that one should
>> be preferred over the others. (Just guessing.)
>
>But I'm guessing wrong, of course. Again, I missed an important
>detail in your post: that alignas is a new C++ keyword (I didn't
>know that). Sorry, I need to pay closer attention.
>
>Given alignas, aligned_storage seems completely superfluous. I
>wonder why it's even still there...
>

The only real benefit is that the name aligned_storage tells exactly
what it does and it provides a default alignment for the requested size.

>Martin
>

Re: question about aligned_storage

Posted by Martin Sebor <se...@roguewave.com>.
Martin Sebor wrote:
> Travis Vitek wrote:
[...]
>>>> The draft shows a 'typical implementation' of aligned_storage that 
>>>> uses the new alignas keyword,
>>>> but alignas doesn't appear to be supported
>>>> anywhere.
>>> That's probably because they didn't want to favor any existing
>>> implementation over others.
>>
>> I don't see this as a problem with the standard not wanting to favor one
>> implementation over another, it is a problem because no current
>> implementation supports the new keyword.
> 
> That might have been the point: use a made up keyword that doesn't
> exist on any implementation so as not to suggest that one should
> be preferred over the others. (Just guessing.)

But I'm guessing wrong, of course. Again, I missed an important
detail in your post: that alignas is a new C++ keyword (I didn't
know that). Sorry, I need to pay closer attention.

Given alignas, aligned_storage seems completely superfluous. I
wonder why it's even still there...

Martin

RE: question about aligned_storage

Posted by Travis Vitek <Tr...@roguewave.com>.
 

Martin Sebor wrote:
>
>Travis Vitek wrote:
>>
>> Here is a testcase...
>> 
>>   $ cat z.cpp && g++ --version && g++ -c z.cpp
>> 
>>   template <int N, int A>
>>   struct __rw_aligned_storage { 
>>       typedef struct {
>>           char _C_align [N] __attribute__ ((aligned (A)));
>>       } type;
>>   };
>> 
>>   __rw_aligned_storage<10, 4>::type aligned_t;
>> 

[...]

>> 
>>   z.cpp: In instantiation of '__rw_aligned_storage<10, 4>::type':
>>   z.cpp:9:   instantiated from here
>>   z.cpp:5: error: requested alignment is not a constant
>> 
>> If I can't access the member type 'type', then the feature 
>> is useless. The nested type is the only thing that is aligned.
>> If you are sure that this will work with gcc-4.3, please show
>> me where I've gone wrong.
>
>Isn't it obvious? You're missing a set of parentheses around A ;-)
>This works for me:
>
>   template <int N, int A>
>   struct __rw_aligned_storage {
>       typedef struct {
>           char _C_align [N] __attribute__ ((aligned ((A))));
>       } type;
>   };
>
>   __rw_aligned_storage<10, 4>::type aligned_t;
>
>> 
>> Travis
>>

Darn you Martin Sebor! Well now that I have a workaround, I can do it
the easy way (on one compiler).

Travis

Re: question about aligned_storage

Posted by Martin Sebor <se...@roguewave.com>.
Travis Vitek wrote:
>  
> 
>> Martin Sebor wrote:
>>
>> Travis Vitek wrote:
>>>  
>>>
>>> I could implement the specializations of the helper for all possible
>>> values up to the upper limit and then let the compiler puke when it
>>> can't honor the alignment that was requested. It is not 
>> 'difficult' to
>>> do this, I just don't see it as useful because I can't test 
>> them until I
>>> have at least one compier that supports the ability to do
>>> non-power-of-two alignments.
>> That was another question I was going to ask although I think I know
>> the answer already: the specialization is only necessary for "crappy
>> compilers" ;-) that require N to be a literal in
>> __attribute__((aligned(N))), right? If so, I suggest providing the
>> specializations only for these, shall we say, "limited" compilers
>> and defining the primary template using the non-type template
>> parameter N for the rest.
> 
> Ummm...
> 
>>>>> The following code is very similar to that typical
>>>>> implementation, but it does not compile because value passed to the
>>>>> aligned attribute has to be a literal, not a constant expression.
>>>> That's what you for using a crappy compiler ;-) It compiles
>>>> with gcc. See
>>>>   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19163
>>> Uh, yeah, it compiles...
>>>
>>>> but watch out for:
>>>>   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36625
>>>>
>>> but it is utterly useless because of this bug. You can't use 
>>> the nested aligned type. Talk about crappy compilers.
>> It isn't completely useless because the attribute can successfully
>> be applied to data members with the same result:
>>
>>     template <int N>
>>     struct A {
>>         struct S {
>>             short f[3]; __attribute__ ((aligned (N)));
>>         };
>>     };
> 
> Here is a testcase...
> 
>   $ cat z.cpp && g++ --version && g++ -c z.cpp
> 
>   template <int N, int A>
>   struct __rw_aligned_storage { 
>       typedef struct {
>           char _C_align [N] __attribute__ ((aligned (A)));
>       } type;
>   };
> 
>   __rw_aligned_storage<10, 4>::type aligned_t;
> 
>   g++ (GCC) 4.3.1
>   Copyright (C) 2008 Free Software Foundation, Inc.
>   This is free software; see the source for copying conditions.  There
> is NO
>   warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
> PURPOSE.
> 
>   z.cpp: In instantiation of '__rw_aligned_storage<10, 4>::type':
>   z.cpp:9:   instantiated from here
>   z.cpp:5: error: requested alignment is not a constant
> 
> If I can't access the member type 'type', then the feature is useless.
> The nested type is the only thing that is aligned. If you are sure that
> this will work with gcc-4.3, please show me where I've gone wrong.

Isn't it obvious? You're missing a set of parentheses around A ;-)
This works for me:

   template <int N, int A>
   struct __rw_aligned_storage {
       typedef struct {
           char _C_align [N] __attribute__ ((aligned ((A))));
       } type;
   };

   __rw_aligned_storage<10, 4>::type aligned_t;

> 
> Travis
> 
>>>> We should open an enhancement request with Microsoft.
>>>>
>>> I'll do that.
>>>
>>>> Martin
>>>>
>>


RE: question about aligned_storage

Posted by Travis Vitek <Tr...@roguewave.com>.
 

>Martin Sebor wrote:
>
>Travis Vitek wrote:
>>  
>> 
>> I could implement the specializations of the helper for all possible
>> values up to the upper limit and then let the compiler puke when it
>> can't honor the alignment that was requested. It is not 
>'difficult' to
>> do this, I just don't see it as useful because I can't test 
>them until I
>> have at least one compier that supports the ability to do
>> non-power-of-two alignments.
>
>That was another question I was going to ask although I think I know
>the answer already: the specialization is only necessary for "crappy
>compilers" ;-) that require N to be a literal in
>__attribute__((aligned(N))), right? If so, I suggest providing the
>specializations only for these, shall we say, "limited" compilers
>and defining the primary template using the non-type template
>parameter N for the rest.

Ummm...

>>>> The following code is very similar to that typical
>>>> implementation, but it does not compile because value passed to the
>>>> aligned attribute has to be a literal, not a constant expression.
>>>
>>> That's what you for using a crappy compiler ;-) It compiles
>>> with gcc. See
>>>   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19163
>> 
>> Uh, yeah, it compiles...
>> 
>>> but watch out for:
>>>   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36625
>>>
>> 
>> but it is utterly useless because of this bug. You can't use 
>> the nested aligned type. Talk about crappy compilers.
>
>It isn't completely useless because the attribute can successfully
>be applied to data members with the same result:
>
>     template <int N>
>     struct A {
>         struct S {
>             short f[3]; __attribute__ ((aligned (N)));
>         };
>     };

Here is a testcase...

  $ cat z.cpp && g++ --version && g++ -c z.cpp

  template <int N, int A>
  struct __rw_aligned_storage { 
      typedef struct {
          char _C_align [N] __attribute__ ((aligned (A)));
      } type;
  };

  __rw_aligned_storage<10, 4>::type aligned_t;

  g++ (GCC) 4.3.1
  Copyright (C) 2008 Free Software Foundation, Inc.
  This is free software; see the source for copying conditions.  There
is NO
  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

  z.cpp: In instantiation of '__rw_aligned_storage<10, 4>::type':
  z.cpp:9:   instantiated from here
  z.cpp:5: error: requested alignment is not a constant

If I can't access the member type 'type', then the feature is useless.
The nested type is the only thing that is aligned. If you are sure that
this will work with gcc-4.3, please show me where I've gone wrong.

Travis

>
>> 
>>> We should open an enhancement request with Microsoft.
>>>
>> 
>> I'll do that.
>> 
>>> Martin
>>>
>
>

Re: question about aligned_storage

Posted by Martin Sebor <se...@roguewave.com>.
Travis Vitek wrote:
>  
> 
> Martin Sebor wrote:
>> Travis Vitek wrote:
>>>  
> 
> [...]
> 
>>> The only functionality I have available 
>>> to me for
>>> doing alignment (on the tested platforms) is __declspec(align(#)) on
>>> Microsoft and __attribute__ ((aligned(#))) on gcc-4.3. Both of these
>>> support functions require that the alignment value be a power of two.
>>> The Microsoft compiler has the 8192 limit.
>> An upper limit is acceptable (it should be mentioned in one of
>> the appendices to the spec). I'm more interested in alignments
>> that aren't powers of 2. It's not clear to me why restricting
>> the template to powers of 2 is okay or why it's difficult not
>> to support all of them up to the limit.
> 
> I'm not saying it is okay to limit them to powers of two, I'm just
> saying that non-power of two values won't work on the platforms that are
> currently supported. The aligned attribute on gcc pukes if you use
> non-power-of-two alignment values.

That's gcc's problem, not ours :) Code involving non-powers of 2
will fail to compile either way, so unless we think that rounding
the request up to the next power of two is the right thing to do
there's nothing we can do about it.

> 
[...]
> 
> I could implement the specializations of the helper for all possible
> values up to the upper limit and then let the compiler puke when it
> can't honor the alignment that was requested. It is not 'difficult' to
> do this, I just don't see it as useful because I can't test them until I
> have at least one compier that supports the ability to do
> non-power-of-two alignments.

That was another question I was going to ask although I think I know
the answer already: the specialization is only necessary for "crappy
compilers" ;-) that require N to be a literal in
__attribute__((aligned(N))), right? If so, I suggest providing the
specializations only for these, shall we say, "limited" compilers
and defining the primary template using the non-type template
parameter N for the rest.

> 
>>> The draft shows a 'typical implementation' of 
>>> aligned_storage that uses the new alignas keyword,
>>> but alignas doesn't appear to be supported
>>> anywhere.
>> That's probably because they didn't want to favor any existing
>> implementation over others.
> 
> I don't see this as a problem with the standard not wanting to favor one
> implementation over another, it is a problem because no current
> implementation supports the new keyword.

That might have been the point: use a made up keyword that doesn't
exist on any implementation so as not to suggest that one should
be preferred over the others. (Just guessing.)

> 
>>> The following code is very similar to that typical
>>> implementation, but it does not compile because value passed to the
>>> aligned attribute has to be a literal, not a constant expression.
>> That's what you for using a crappy compiler ;-) It compiles
>> with gcc. See
>>   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19163
> 
> Uh, yeah, it compiles...
> 
>> but watch out for:
>>   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36625
>>
> 
> but it is utterly useless because of this bug. You can't use the nested
> aligned type. Talk about crappy compilers.

It isn't completely useless because the attribute can successfully
be applied to data members with the same result:

     template <int N>
     struct A {
         struct S {
             short f[3]; __attribute__ ((aligned (N)));
         };
     };

> 
>> We should open an enhancement request with Microsoft.
>>
> 
> I'll do that.
> 
>> Martin
>>


RE: question about aligned_storage

Posted by Travis Vitek <Tr...@roguewave.com>.
 

Martin Sebor wrote:
>
>Travis Vitek wrote:
>>  

[...]

>>
>> The only functionality I have available 
>> to me for
>> doing alignment (on the tested platforms) is __declspec(align(#)) on
>> Microsoft and __attribute__ ((aligned(#))) on gcc-4.3. Both of these
>> support functions require that the alignment value be a power of two.
>> The Microsoft compiler has the 8192 limit.
>
>An upper limit is acceptable (it should be mentioned in one of
>the appendices to the spec). I'm more interested in alignments
>that aren't powers of 2. It's not clear to me why restricting
>the template to powers of 2 is okay or why it's difficult not
>to support all of them up to the limit.

I'm not saying it is okay to limit them to powers of two, I'm just
saying that non-power of two values won't work on the platforms that are
currently supported. The aligned attribute on gcc pukes if you use
non-power-of-two alignment values.

  $ cat z.cpp; g++ z.cpp && a.out

  int main ()
  {
      typedef char dummy __attribute__ ((aligned(3)));
      return 0;
  }
  z.cpp: In function 'int main()':
  z.cpp:4: error: requested alignment is not a power of 2

I could implement the specializations of the helper for all possible
values up to the upper limit and then let the compiler puke when it
can't honor the alignment that was requested. It is not 'difficult' to
do this, I just don't see it as useful because I can't test them until I
have at least one compier that supports the ability to do
non-power-of-two alignments.

>> 
>> The draft shows a 'typical implementation' of 
>> aligned_storage that uses the new alignas keyword,
>> but alignas doesn't appear to be supported
>> anywhere.
>
>That's probably because they didn't want to favor any existing
>implementation over others.

I don't see this as a problem with the standard not wanting to favor one
implementation over another, it is a problem because no current
implementation supports the new keyword.

>
>> The following code is very similar to that typical
>> implementation, but it does not compile because value passed to the
>> aligned attribute has to be a literal, not a constant expression.
>
>That's what you for using a crappy compiler ;-) It compiles
>with gcc. See
>   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19163

Uh, yeah, it compiles...

>
>but watch out for:
>   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36625
>

but it is utterly useless because of this bug. You can't use the nested
aligned type. Talk about crappy compilers.

>We should open an enhancement request with Microsoft.
>

I'll do that.

>Martin
>

Re: question about aligned_storage

Posted by Martin Sebor <se...@roguewave.com>.
Travis Vitek wrote:
>  
> 
> Martin Sebor wrote:
[...]
>> I'm probably missing something but is aligned_storage only specified
>> for alignment of powers of 2? (It looks to me as though those are the
>> only alignments we support.)
> 
> Yes. I probably need to do something here, but I'm not sure what. Table
> 51 says
> 
>   _Align shall be equal to alignment_of<T>::value for some type
>   T or to `default-alignment'
> 
> This essentially says that I need to support all valid alignment values
> on the platform. Fortunately, for the time being the power of two
> restriction is okay. The only functionality I have available to me for
> doing alignment (on the tested platforms) is __declspec(align(#)) on
> Microsoft and __attribute__ ((aligned(#))) on gcc-4.3. Both of these
> support functions require that the alignment value be a power of two.
> The Microsoft compiler has the 8192 limit.

An upper limit is acceptable (it should be mentioned in one of
the appendices to the spec). I'm more interested in alignments
that aren't powers of 2. It's not clear to me why restricting
the template to powers of 2 is okay or why it's difficult not
to support all of them up to the limit.

> 
> The draft shows a 'typical implementation' of aligned_storage that uses
> the new alignas keyword, but alignas doesn't appear to be supported
> anywhere.

That's probably because they didn't want to favor any existing
implementation over others.

> The following code is very similar to that typical
> implementation, but it does not compile because value passed to the
> aligned attribute has to be a literal, not a constant expression.

That's what you for using a crappy compiler ;-) It compiles
with gcc. See
   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19163

but watch out for:
   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36625

We should open an enhancement request with Microsoft.

Martin

> 
>   template <std::size_t _Size,
>             std::size_t _Align = __rw_default_alignment<_Size>::value>
>   struct __rw_aligned_storage
>   {
>       typedef struct {
>           char _C_align [_Size] __attribute__ ((aligned(_Align)));
>       } type;
>   };
> 
> Travis
> 
>> Martin
>>
>>>> See http://tinyurl.com/5kmvdy for reference.
>>>>
>>>> Martin
>>>>
>>>>
>>


RE: question about aligned_storage

Posted by Travis Vitek <Tr...@roguewave.com>.
 

Martin Sebor wrote:
>
>Travis Vitek wrote:
>>  
>> Martin Sebor wrote:
>>> While looking at the hoops we jump through to implement 
>>> aligned_storage
>>> I recalled the gcc __attribute__ (aligned (N)). Is there 
>>> any to use it to simplify the implementation for gcc?
>> 
>> We already do.
>
>You're a step (or a few) ahead of me, as usual... :)

You give me more credit than I deserve. I'm making this stuff up as I
go... :)

>
>> Have a look at the definition of the macro
>> _RWSTD_TT_ALIGNED_POD().
>
>You mean the one in rw/_gcc-config.h on the 103 character long line?
>(You almost got away with it ;-)
>

Yeah, I have a few long lines. I need to clean up the mess that I've
made.

>> 
>> I might be able to eliminate __rw_aligned_storage_impl<> if 
>> I wanted to
>> do a partial specialization of __rw_aligned_storage<> on the _Align
>> non-type template parameter and I could also eliminate
>> __rw_default_alignment<>, but that is about as much as I 
>> think I could reduce it.
>
>I'm probably missing something but is aligned_storage only specified
>for alignment of powers of 2? (It looks to me as though those are the
>only alignments we support.)

Yes. I probably need to do something here, but I'm not sure what. Table
51 says

  _Align shall be equal to alignment_of<T>::value for some type
  T or to `default-alignment'

This essentially says that I need to support all valid alignment values
on the platform. Fortunately, for the time being the power of two
restriction is okay. The only functionality I have available to me for
doing alignment (on the tested platforms) is __declspec(align(#)) on
Microsoft and __attribute__ ((aligned(#))) on gcc-4.3. Both of these
support functions require that the alignment value be a power of two.
The Microsoft compiler has the 8192 limit.

The draft shows a 'typical implementation' of aligned_storage that uses
the new alignas keyword, but alignas doesn't appear to be supported
anywhere. The following code is very similar to that typical
implementation, but it does not compile because value passed to the
aligned attribute has to be a literal, not a constant expression.

  template <std::size_t _Size,
            std::size_t _Align = __rw_default_alignment<_Size>::value>
  struct __rw_aligned_storage
  {
      typedef struct {
          char _C_align [_Size] __attribute__ ((aligned(_Align)));
      } type;
  };

Travis

>
>Martin
>
>> 
>>> See http://tinyurl.com/5kmvdy for reference.
>>>
>>> Martin
>>>
>>>
>
>

Re: question about aligned_storage

Posted by Martin Sebor <se...@roguewave.com>.
Travis Vitek wrote:
>  
> 
> Martin Sebor wrote:
>> While looking at the hoops we jump through to implement aligned_storage
>> I recalled the gcc __attribute__ (aligned (N)). Is there any to use it
>> to simplify the implementation for gcc?
> 
> We already do.

You're a step (or a few) ahead of me, as usual... :)

> Have a look at the definition of the macro
> _RWSTD_TT_ALIGNED_POD().

You mean the one in rw/_gcc-config.h on the 103 character long line?
(You almost got away with it ;-)

> 
> I might be able to eliminate __rw_aligned_storage_impl<> if I wanted to
> do a partial specialization of __rw_aligned_storage<> on the _Align
> non-type template parameter and I could also eliminate
> __rw_default_alignment<>, but that is about as much as I think I could
> reduce it.

I'm probably missing something but is aligned_storage only specified
for alignment of powers of 2? (It looks to me as though those are the
only alignments we support.)

Martin

> 
>> See http://tinyurl.com/5kmvdy for reference.
>>
>> Martin
>>
>>


RE: question about aligned_storage

Posted by Travis Vitek <Tr...@roguewave.com>.
 

Martin Sebor wrote:
>
>While looking at the hoops we jump through to implement aligned_storage
>I recalled the gcc __attribute__ (aligned (N)). Is there any to use it
>to simplify the implementation for gcc?

We already do. Have a look at the definition of the macro
_RWSTD_TT_ALIGNED_POD().

I might be able to eliminate __rw_aligned_storage_impl<> if I wanted to
do a partial specialization of __rw_aligned_storage<> on the _Align
non-type template parameter and I could also eliminate
__rw_default_alignment<>, but that is about as much as I think I could
reduce it.

>
>See http://tinyurl.com/5kmvdy for reference.
>
>Martin
>
>