Problems with void Template Type Parameters and Zero-Length Arrays

Discussion in 'C++' started by Matt Taylor, Sep 23, 2004.

  1. Matt Taylor

    Matt Taylor Guest

    I am trying to use templates to create an optimal structure for a fixed-size
    buffer that holds a homogenous array of elements. For brevity, this problem
    is somewhat simplified from my implementation:

    template<typename T1, size_t len>
    struct buffer_t
    {
    // Array of elements
    T1 ary[len / sizeof(T1)];

    // Align upward to a multiple of sizeof(T1)
    char pad[len - ((len / sizeof(T1)) * sizeof(T1))];
    };

    The problem is that, when len is a multiple of sizeof(T1), the pad variable
    has length 0. For some reason the compiler finds this to be absurd. I need
    to find some way to make this compile in that case. Is there any simple
    resolution to this?

    I am also wondering about the following:
    template<typename T>
    struct A
    {
    int a;
    T b;
    };

    struct INGET
    {
    };

    Why is A<INGET> legal but not A<void>? Semantically they would be the same,
    right?

    -Matt
    Matt Taylor, Sep 23, 2004
    #1
    1. Advertising

  2. Matt Taylor wrote in news:nQn4d.45958$
    in comp.lang.c++:

    >
    > The problem is that, when len is a multiple of sizeof(T1), the pad
    > variable has length 0. For some reason the compiler finds this to be
    > absurd. I need to find some way to make this compile in that case. Is
    > there any simple resolution to this?
    >


    #include <iostream>
    #include <cstddef>

    using std::size_t;

    template <typename T1, size_t len>
    struct padding
    {
    static size_t const value = len - ((len / sizeof(T1)) * sizeof(T1));
    };

    template < typename T, size_t Count, size_t Pad >
    struct base_buffer_t
    {
    T ary[ Count ];
    char pad[ Pad ];
    };

    template < typename T, size_t Count >
    struct base_buffer_t< T, Count, 0U >
    {
    T ary[ Count ];
    typedef void pad; /* for using */
    };


    template <typename T1, size_t len>
    struct buffer_t :
    private base_buffer_t<
    T1, len / sizeof(T1), len - ((len / sizeof(T1)) * sizeof(T1))
    >

    {
    private:

    typedef base_buffer_t<
    T1, len / sizeof(T1), len - ((len / sizeof(T1)) * sizeof(T1))
    >

    base_t
    ;

    public:

    using base_t::ary;
    using base_t::pad;
    };


    int main()
    {
    buffer_t< int, sizeof( int ) * 2 > int2;
    int2.ary[1] = 2;

    buffer_t< int, (sizeof( int ) * 1) + 1 > int1p1;

    std::cout << sizeof( int2 ) << '\n';
    std::cout << sizeof( int1p1 ) << '\n';
    }


    > I am also wondering about the following:
    > template<typename T>
    > struct A
    > {
    > int a;


    This next line can't compile if the substitution T = void is done.

    > T b;
    > };
    >
    > struct INGET
    > {
    > };
    >
    > Why is A<INGET> legal but not A<void>? Semantically they would be the
    > same, right?
    >


    Its illegal because:

    void b;

    is illegal, i.e. you cannot declare objects of type void.

    HTH.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, Sep 23, 2004
    #2
    1. Advertising

  3. Matt Taylor

    Matt Taylor Guest

    "Rob Williscroft" <> wrote in message
    news:Xns956D7E699DB5ukcoREMOVEfreenetrtw@130.133.1.4...
    > Matt Taylor wrote in news:nQn4d.45958$
    > in comp.lang.c++:

    [...]
    > Its illegal because:
    >
    > void b;
    >
    > is illegal, i.e. you cannot declare objects of type void.


    Yeah, I know. I was mostly wondering the logic behind why one can create and
    instantiate a structure with length 0 but not an object of type void since
    they seem to me to be the same idea. This is very strange because you can
    create a typedef which is just an alias for void, but you can't use void
    itself.

    Anyhow, thank you for your reply -- it has helped greatly.

    -Matt
    Matt Taylor, Sep 24, 2004
    #3
  4. Matt Taylor

    Ron Natalie Guest

    "Matt Taylor" <com.sisecure@mtaylor> wrote in message news:gf05d.54657$...

    >
    > Yeah, I know. I was mostly wondering the logic behind why one can create and
    > instantiate a structure with length 0 but not an object of type void since
    > they seem to me to be the same idea.


    You can't create a structure of size 0. You can create a structure with no data
    members in it, but it will still have size greater than zero.
    Ron Natalie, Sep 24, 2004
    #4
  5. Matt Taylor

    Old Wolf Guest

    "Matt Taylor" <com.sisecure@mtaylor> wrote:
    > I am trying to use templates to create an optimal structure for a fixed-size
    > buffer that holds a homogenous array of elements. For brevity, this problem
    > is somewhat simplified from my implementation:
    >
    > template<typename T1, size_t len>
    > struct buffer_t
    > {
    > // Array of elements
    > T1 ary[len / sizeof(T1)];
    >
    > // Align upward to a multiple of sizeof(T1)
    > char pad[len - ((len / sizeof(T1)) * sizeof(T1))];
    > };
    >
    > The problem is that, when len is a multiple of sizeof(T1), the
    > pad variable has length 0.


    Do you need to be able to reference 'pad' ? If not then you
    could try:

    template<typename T1, size_t len>
    union buffer_t
    {
    T1 ary[len / sizeof(T1)];
    char pad[len];
    };

    (If you need other data members in buffer_t then you would
    have to make it a struct, and have a member union).
    Old Wolf, Sep 26, 2004
    #5
  6. Matt Taylor

    Matt Taylor Guest

    "Old Wolf" <> wrote in message
    news:...
    > "Matt Taylor" <com.sisecure@mtaylor> wrote:

    [...]
    > > The problem is that, when len is a multiple of sizeof(T1), the
    > > pad variable has length 0.

    >
    > Do you need to be able to reference 'pad' ? If not then you
    > could try:
    >
    > template<typename T1, size_t len>
    > union buffer_t
    > {
    > T1 ary[len / sizeof(T1)];
    > char pad[len];
    > };


    Ah, I had not thought of this. This is a very simple and intuitive way to
    make it work.

    My thanks and appreciation to both posters.

    -Matt
    Matt Taylor, Sep 28, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?SG96aQ==?=
    Replies:
    1
    Views:
    6,954
    Ken Cox [Microsoft MVP]
    Jun 2, 2004
  2. Ollej Reemt
    Replies:
    7
    Views:
    524
    Jack Klein
    Apr 22, 2005
  3. Stig Brautaset

    `void **' revisited: void *pop(void **root)

    Stig Brautaset, Oct 25, 2003, in forum: C Programming
    Replies:
    15
    Views:
    786
    The Real OS/2 Guy
    Oct 28, 2003
  4. Replies:
    5
    Views:
    825
    S.Tobias
    Jul 22, 2005
  5. Replies:
    1
    Views:
    405
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page