Thread: GCC:Static(fixed-length) array in template class

  1. #1
    Registered User
    Join Date
    Jun 2010
    Location
    norway
    Posts
    3

    GCC:Static(fixed-length) array in template class

    Hi.

    I'm using GCC's c++ compiler, and when attempting to create a template class containing an N-length array;

    Code:
    template <int N>
    class C
    {
    public:
        { ... }
    private:
        { ... }
        int _array[N];
    };
    ... and start using(i.e. calling functions manipulationg C::_array) a single instance of the class; everything is fine. But when several instances exist, the array is zeroed-out, and stays that way.

    If I use a dynamic array, then no problem. Is there any way to get fixed-length arrays as class-members in GCC-c++?

    Thanks in advance!
    Last edited by tra86; 06-19-2011 at 01:52 PM. Reason: Unclarity

  2. #2
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Quote Originally Posted by tra86 View Post
    ... and start using(i.e. calling functions manipulationg C::_array) a single instance of the class; everything is fine. But when several instances exist, the array is zeroed-out, and stays that way.
    It is very likely that the problem exists somewhere else. You might, for example, be writing to global C instances, while reading the local ones. You have to provide more code or a complete compilable example.

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Since the C++ standard does not support VLA (Variable Length Arrays) I would recommend that you use std::vector, dynamic memory, or possibly std::array if you are compiling with C++0x. Although g++ may support VLA as a compiler extension I would not recommend using this extension because until gcc version 4.5 VLA are listed as broken.

    Jim

  4. #4
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    That's not a VLA.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by jimblumberg View Post
    Since the C++ standard does not support VLA (Variable Length Arrays) I would recommend that you use std::vector, dynamic memory, or possibly std::array if you are compiling with C++0x. Although g++ may support VLA as a compiler extension I would not recommend using this extension because until gcc version 4.5 VLA are listed as broken.

    Jim
    This is perfectly fine since N is known at compile time (this is how std::array is implemented).

    There is not enough to actually identify the problem, so I would suggest you try to make a smallest compilable example that demonstrates the problem.

    Btw, a name that begins with an underscore and a small letter is reserved for implementation use. You should not use that.
    Last edited by Elysia; 06-19-2011 at 04:19 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    There is nothing wrong with the snippet posted.

    As kmdv said, the problem is elsewhere.

    Soma

  7. #7
    Registered User
    Join Date
    Jun 2010
    Location
    norway
    Posts
    3
    Hi. I found the problem and as you said, the problem was elsewhere; marked in the following code.

    Code:
    template <typename T, std::size_t NDimensions>
    class Vector
    {
    public:
    	typedef T value_type;
    	typedef std::size_t size_type;
    	
    	enum { dimensions = NDimensions };
    	
    	Vector(std::initializer_list<value_type> list) 
    	{
    		init();
    		
    		size_type ix = 0;
    		for (typename std::initializer_list<value_type>::iterator it = list.begin();
    			it != list.end(); ++it, ++ix)
    		{
    			_values[ix] = *it;
    		}
    	}
    	
    	Vector(const Vector &rhs)
    	{
    		init();
    		
    		for (size_type i = 0; i < dimensions; ++i)
    		{
    			_values[i] = rhs._values[i];
    		}
    	}
    	
    	Vector()
    	{
    		init();
    		
                    // Problem was Here:
    		memset(_values, 0, sizeof(_values) * sizeof(*_values));
                    // Changed it to
                    // -- memset(_values, 0, dimensions * sizeof(value_type));
    	}
    	
    	~Vector()
    	{
    		//delete _values;
    	}
    	
    	Vector &operator=(const Vector &rhs)
    	{
    		for (size_type i = 0; i < dimensions; ++i)
    		{
    			_values[i] = rhs._values[i];
    		}
    		
    		return *this;
    	}
    	
    	value_type &operator[](size_type index)
    	{
    		return _values[index];
    	}
    	
    	const value_type &operator[](size_type index) const
    	{
    		return _values[index];
    	}
    	
    private:
    	void init()
    	{
    		//_values = new value_type[dimensions];
    	}
    
    	//value_type *_values;
            value_type _values[dimensions];
    };
    Now it works as a static array, i can see it from the object size. Thanks for all the replies!

    I still don't get why memset(_values, 0, sizeof(_values) * sizeof(*_values)); works for a dynamic but not for a fixed-length array thou, but thats not so important.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    In your initializer list constructor, make sure the length of the initializer list is not greater than the size of your array!
    Also, memset is not recommended in C++. Actually, it's outright dangerous. Use std::fill instead.

    And actually,
    memset(_values, 0, sizeof(_values) * sizeof(*_values));
    would not work for a dynamic length array since sizeof(_values) would be the size of the pointer, and not the array.
    Also, sizeof returns the entire size (in bytes) of the array, so don't multiply it with anything.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Btw, a name that begins with an underscore and a small letter is reserved for implementation use. You should not use that.
    I thought it was just names beginning with a double underscore or an underscore and an uppercase letter that were reserved?

    Quote Originally Posted by tra86 View Post
    I still don't get why memset(_values, 0, sizeof(_values) * sizeof(*_values)); works for a dynamic but not for a fixed-length array thou, but thats not so important.
    Like Elysia said, this would cause a buffer overflow. You're filling too much memory, a factor of sizeof(*_values) more memory than you should be touching, with that code.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by dwks View Post
    I thought it was just names beginning with a double underscore or an underscore and an uppercase letter that were reserved?
    My memory served me wrong. You are correct.
    To make it a (little) easier, one might remember to avoid all names starting with an underscore.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Static member initialization with class template
    By threahdead in forum C++ Programming
    Replies: 6
    Last Post: 04-28-2011, 12:16 AM
  2. how to define a static member in a template class
    By wanziforever in forum C++ Programming
    Replies: 3
    Last Post: 10-08-2009, 04:44 AM
  3. Linking error with static template class members
    By cunnus88 in forum C++ Programming
    Replies: 6
    Last Post: 04-02-2009, 12:31 PM
  4. tricky: static int on template class;
    By FillYourBrain in forum C++ Programming
    Replies: 5
    Last Post: 11-26-2002, 04:03 PM
  5. bug for static functions in template class
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 09-16-2001, 06:38 PM