Initalize an array in constructor

This is a discussion on Initalize an array in constructor within the C++ Programming forums, part of the General Programming Boards category; Hey guys the below code works fine and i get the correct result but I fear I am coding dangerously ...

  1. #1
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,479

    Initalize an array in constructor

    Hey guys the below code works fine and i get the correct result but I
    fear I am coding dangerously here. Its usually better to have the
    constructor inialize the array elements to zero before I enter the values
    but when i tried this:

    Code:
    m_Array1[ m_ARRAY_SIZE ] = { 0 }
    Inside the constructoir I got an error. Would it be a better idea to have the
    constructor call a seperate function that does the above?

    Code:
    #include <iostream>
    #include <iomanip>
    
    class ArrayClass
    {
    public:
       ArrayClass();
       ~ArrayClass();
    
       void inputArrayData();
       void outputArrayData();
    
    private:
       static const int m_ARRAY_SIZE = 10;
       int m_Array1[ m_ARRAY_SIZE ];
       int m_Array2[ m_ARRAY_SIZE ];
    };
    
    ArrayClass::ArrayClass()
    {
       m_Array1[ m_ARRAY_SIZE ];
       m_Array2[ m_ARRAY_SIZE ];
    }
    
    ArrayClass::~ArrayClass()
    {
       std::cout << "\nDestructor called....\n";
    }
    
    void ArrayClass::inputArrayData()
    {
       std::cout << "Enter values for array1: ";
    
       for ( int i = 0; i < m_ARRAY_SIZE; i++ )
       {
          std::cin >> m_Array1[ i ];
       }
    
       std::cout << "\nEnter values for array2: ";
    
       for ( int i = 0; i < m_ARRAY_SIZE; i++ )
       {
          std::cin >> m_Array2[ i ];
       }
    }
    
    void ArrayClass::outputArrayData()
    {
       std::cout << "ARRAY 1" << std::setw( 12 ) << "VALUE\n\n";
    
       for ( int i = 0; i < 10; i++ )
       {
          std::cout << std::setw( 3 ) << i << std::setw( 14 ) << m_Array1[ i ]
                    << std::endl;
       }
    
       std::cout << "\nARRAY 2" << std::setw( 12 ) << "VALUE\n\n";
    
       for ( int i = 0; i < 10; i++ )
       {
          std::cout << std::setw( 3 ) << i << std::setw( 14 ) << m_Array2[ i ]
                    << std::endl;
       }
    }
    
    // main - begins program execution /////////////////////////////////////////////
    //
    int main(int argc, char *argv[])
    {
       ArrayClass ac;
    
       ac.inputArrayData();
       ac.outputArrayData();
    
       std::cin.get(); // freeze console output window
       std::cin.ignore();
    
       return 0; // return value from main to OS
    }
    Last edited by swgh; 11-17-2007 at 05:27 AM. Reason: Mis-spelt word
    I'm just trying to be a better person - My Name Is Earl

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,886
    I think you are looking to write:
    Code:
    ArrayClass::ArrayClass() : m_Array1(), m_Array2()
    {
    }
    The m_Array1[ m_ARRAY_SIZE ] and m_Array2[ m_ARRAY_SIZE ] in your constructor is actually just accessing the arrays out of bound, yet having no net effect.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,308
    This behaviour does depend on what compiler you're using though.
    Pre VS2005 doesn't do what you want. See http://msdn2.microsoft.com/en-us/lib...cy(VS.80).aspx
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,338
    Is that behavior guaranteed by the standard? I would think it is not and is just an extension for VC++, but I'm not sure.

    I also wonder if std::tr1::array is guaranteed to default initialize its array elements.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,886
    Is that behavior guaranteed by the standard?
    I think it is:
    Quote Originally Posted by Section 8.5 of the C++ Standard (2003)
    To value-initialize an object of type T means:
    ...
    - if T is an array type, then each element is value-initialized;
    - otherwise, the object is zero-initialized

    ...

    An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
    Then:
    Quote Originally Posted by Section 12.6 of the C++ Standard (2003)
    When no initializer is specified for an object of (possibly cv-qualified) class type (or array thereof), or the initializer has the form (), the object is initialized as specified in 8.5. The object is default-initialized if there is no initializer, or value-initialized if the initializer is ().
    My interpretation is that ": m_Array1(), m_Array2()" result in both arrays being value initialised. As such, each int in the respective array is zero-initialised. This works on both MSVC8 (VS2005) and the MinGW port of g++ 3.4.2.

    EDIT:
    Just came back from my late night shower, and I think I spotted a mistake: 12.6.0 is concerned with the initialisation of the object, not its members. The correct quote is:
    Quote Originally Posted by Section 12.6.2 of the C++ Standard (2003
    In the definition of a constructor for a class, initializers for direct and virtual base subobjects and nonstatic data members can be specified by a ctor-initializer, which has the form ctor-initializer:
    Code:
        : mem-initializer-list
    mem-initializer-list:
        mem-initializer
        mem-initializer , mem-initializer-list
    mem-initializer:
        mem-initializer-id ( expression-list ) // expression-list is optional
    ...

    The expression-list in a mem-initializer is used to initialize the base class or nonstatic data member subobject denoted by the mem-initializer-id. The semantics of a mem-initializer are as follows:
    - if the expression-list of the mem-initializer is omitted, the base class or member subobject is value initialized (see 8.5);
    To confirm that excluding m_Array1 and m_Array2 from the constructor initialisation list should leave their elements uninitialised:
    Quote Originally Posted by Section 12.6.2 of the C++ Standard (2003)
    If a given nonstatic data member or base class is not named by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer), then
    - If the entity is a nonstatic data member of (possibly cv-qualified) class type (or array thereof) or a base class, and the entity class is a non-POD class, the entity is default-initialized (8.5). If the entity is a nonstatic data member of a const-qualified type, the entity class shall have a user-declared default constructor.
    - Otherwise, the entity is not initialized. If the entity is of const-qualified type or reference type, or of a (possibly cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of a const-qualified type, the program is ill-formed.
    Last edited by laserlight; 11-17-2007 at 02:01 PM.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    Not wanting to hijack the thread but this init stuff caught my eye.

    If this is part of the standard then I should theoretically be able to do this on any new compiler?

    Also this means that by providing an array in the intializer list for member arrays I would be essentially forcing the compiler to do a memset(array,0,array_size) correct? I'm not so sure I would want to do that in all instances.
    Last edited by VirtualAce; 11-17-2007 at 03:37 PM.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,886
    If this is part of the standard then I should theoretically be able to do this on any new compiler?
    ... that conforms to the C++ Standard with respect to this particular language feature. Considering that Microsoft changed the compiler behaviour to have this new behaviour, and that g++ implements this new behaviour, I would hazard a guess that previous versions of Microsoft's compilers, even MSVC7.1, does not conform to the standard in this respect.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    Well the MSDN docs say that the arrays would not always be initialized. Perhaps this was a bug they never got around to fixing in previous versions? But this would mean that relying on such a mechanism in earlier MS compilers would be relying on undefined compiler behavior.

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,047
    I took swgh's original code with laserlight's modification
    Code:
    ArrayClass::ArrayClass() : m_Array1(), m_Array2()
    {
    }
    and compiled it with Dinkumware. Here are the results.

    VC++ v8/C++, VC++ for CE 5.0/C++, and VC++ v8 Express/C++: some warnings (my escaped lines)
    Code:
    sourceFile.cpp(20) : warning C4351: new behavior: elements of array\
     'ArrayClass::m_Array1' will be default initialized
    sourceFile.cpp(20) : warning C4351: new behavior: elements of array\
     'ArrayClass::m_Array2' will be default initialized
    VC++ v7/C++ and VC++ v7.1/C++: no warnings or errors
    VC++ v6/C++ and eVC++ v4.0/C++: compile fails with a multitude of errors
    EDG/C++, EDG/Abridged, and EDG/C99: no warnings or errors
    MinGW/C++: no warnings or errors

    I didn't include EDG/EC++ because it can't even find the std:: namespace . . .

    [edit] 5,500th post! [/edit]
    Last edited by dwks; 11-17-2007 at 03:59 PM.
    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
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    Interesting. Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Modify an single passed array element
    By swgh in forum C Programming
    Replies: 3
    Last Post: 08-04-2007, 08:58 AM
  2. 1-D array
    By jack999 in forum C++ Programming
    Replies: 24
    Last Post: 05-12-2006, 07:01 PM
  3. Passing array through class constructor
    By sonicdoomx in forum C++ Programming
    Replies: 4
    Last Post: 05-10-2006, 01:42 PM
  4. Template Array Class
    By hpy_gilmore8 in forum C++ Programming
    Replies: 15
    Last Post: 04-11-2004, 11:15 PM
  5. two dimensional dynamic array?
    By ichijoji in forum C++ Programming
    Replies: 6
    Last Post: 04-14-2003, 04:27 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21