Array Definition

Hello,I have a question.
When give a definition,is there any difference between

int a[]={1,1,2,2,3};
and
int a[5]={1,1,2,2,3};

Then,How about a[6]={1,1,2,2,3}; Is this form valid?
Thank you.
Hi,

Q1 - no. If one leaves out the size of the array and brace initialise it, then the compiler counts the size of the array. However if one needs to know the size of the array later, then it is more work.

Q2. Yes, but the last position will likely contain garbage, so one should avoid doing that. Always fully initialise variables with something.

Also, try to avoid having magic numbers like 5 in your code, make it a constant variable instead, and use that variable name.

1
2
3
const std::size_t ArraySize = 5;

MyArray[ArraySize] = { 1,1,2,2,3 };


std::size_t is an unsigned type used for the size of something, you could use any of the unsigned integral types here if you want.

Use of std::array is generally preferred over an ordinary array - it is aware of it size for one thing.

Also consider std::vector - this can be resized automatically or at will, so it is very handy for lots of things.

Good Luck :+)
> but the last position will likely contain garbage

No. The rules for aggregate initialization apply. http://en.cppreference.com/w/cpp/language/aggregate_initialization

1
2
3
4
5
6
7
8
9
10
11
12
13
int a[5] {} ; // [0,0,0,0,0]

int b[5] = {} ; // [0,0,0,0,0]

int c[5] { 5, 8 } ; // [5,8,0,0,0]

// int d[5] = { 3, 7, 8, 5, 4, 2 } ; // *** error: too many initialisers

int e[] { 6, 7, 8 } ; // [6,7,8] ; // size of array is 3

int f[4][3] { { 3, 7, 8 }, { 5, 4, 2 }, {9} } ; // [ [3,7,8] [5,4,2] [9,0,0] [0,0,0] ]

int g[4][3] = { 3, 7, 8, 5, 4, 2, 9 } ; // [ [3,7,8] [5,4,2] [9,0,0] [0,0,0] ] (brace-elision) 
Be aware that array and struct can be initialized as well with {} but struct will not allow you to set partially an instance.
1
2
3
4
5
6
7
8
9
10
11
12
 
struct Window
{
 int width;
 int height;
 HWND hHandle;
};

 Window win = {800,600 , NULL};

The order must be respect in function of the data order of the struct , by the way.




To answer the first question about [] and [number] . Because the [] is a c array or also called build-in array , the compiler will know the size of the array when the size is not explicit . This is valid also for [][] , but must be specified on function parameters like so [][number].

Providing a size explicitly removes also some effort during compilation , not so signficant but...

The moment you should use [] is when you declared the array but you might add or remove element in further programming , until your array is fixed size and then you write the size. It might be obvious when having less than 10 , but if you write about 100 elements , you should write the size between [ ] . The size is also used by you to iterate and prevent out-range.
struct will not allow you to set partially an instance.
They will allow to do that.
In JLBorges link:
If the number of initializer clauses is less than the number of members or initializer clauses is completely empty, the remaining members are initialized by their brace-or-equal initializers, if provided in the class definition, and otherwise (since C++14) by empty lists, which performs value-initialization. If a member of a reference type is one of these remaining members, the program is ill-formed (references cannot be value-initialized)

In value initialization after information related to classes (not interesting for us as HWND is void*, not class) and arrays:
Otherwise, the object is zero-initialized.

In zero-initialization:
If T is a scalar type, the object's initial value is the integral constant zero explicitly converted to T.
since c++ 14 ? I dont think most compilers supports it neither c++ 17 . But that 's good to know .

But be aware that generally the default constructor is called for that kind of support , but what if your constructors are private ? I know that this is a little out of context , but ...
Last edited on
> since c++ 14 ? I dont think most compilers supports it neither c++ 17 .

The LLVM and GNU compilers do (with -std=c++14)
The Microsoft compiler, current version (19.00), does not.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

struct S { int a ; int b ; int c = 9 ; };

std::ostream& operator<< ( std::ostream& stm, const S& s )
{ return stm << "S{ a:" << s.a << ", b:" << s.b << " c:" << s.c << " }" ; }

int main ()
{
    S a {} ; std::cout << a << '\n' ; // S{ a:0, b:0 c:9 }

    S b = {} ; std::cout << b << '\n' ; // S{ a:0, b:0 c:9 }

    S c { 1, 2 } ; std::cout << c << '\n' ; // S{ a:1, b:2 c:9 }

    S d = { 1 } ; std::cout << d << '\n' ; // S{ a:1, b:0 c:9 }
}

uname -a
echo && clang++ --version | grep clang && clang++ -std=c++14 -stdlib=libc++ -O3 -Wall -Wextra -pedantic-errors -Wno-missing-field-initializers main.cpp && ./a.out
echo && g++ --version | grep GCC && g++ -std=c++14 -O3 -Wall -Wextra -pedantic-errors -Wno-missing-field-initializers main.cpp && ./a.out
Linux stacked-crooked 3.2.0-74-virtual #109-Ubuntu SMP Tue Dec 9 17:04:48 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

clang version 3.6.0 (tags/RELEASE_360/final 235480)
S{ a:0, b:0 c:9 }
S{ a:0, b:0 c:9 }
S{ a:1, b:2 c:9 }
S{ a:1, b:0 c:9 }

g++ (GCC) 5.2.0
S{ a:0, b:0 c:9 }
S{ a:0, b:0 c:9 }
S{ a:1, b:2 c:9 }
S{ a:1, b:0 c:9 }

http://coliru.stacked-crooked.com/a/53aa8b05093d0cfb
Last edited on

I should have a look to that then :)
since c++ 14
It would be easier if you look in original link. Since C++14 relates to brace-or-equal initializers, if provided in the class definition. That is why it is not bold. Non-complete braced-init-lists for POD class types were allowed in the very first C++ standard AFAIK. Further revisions relaxed restrictons on types for which aggregate-initialization is allowed.
I dont think most compilers supports it neither c++ 17
All major compilers support C++14 (I believe GCC and Clang fully support C++14, when Visual studio lacks some more obscure features and full constexpr support and Intel compiler implements only basic needed functionality)
@MiiNiPaa which obscure features are you referring to ?
Variable templates, allowing aggregate initialization for classes with brace-or-equal initializers (that very feature that confused you) and expression SFINAE (C++11 feature).
for the SFINAE , there is a keyword
explicit
for constructors , but yeah , this is obscure sometimes . Variable templates hmm never use it . The thing people need to know is that template is kind of creating copies . So in my opinion a variable template , if in the code was used with different type , will then create necessary copies(instantiate) of the variable in the class but visible in the assembly code . That would necessarily increase the size of the class. So I would not use it in optimization.

The only thing to know is that even if the code (c++14) is prettier , assembly does not change from the c++11 to 14 , the semantic did only .

What is great with that is that speed and productivity is very important these days in enterprise and so that kind of semantics will improve that . But the code wont be faster.

for the SFINAE , there is a keyword
explicit
for constructors ,
Which has nothing to do with SFINAE. Here is a proposal which explains problem: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html

variable templates is a nessesary addition to avoid all those ugly some_helper<T>::value There is a bunch proposed for C++17: http://en.cppreference.com/w/cpp/experimental/type_trait_variable_templates
And of course their addition will not change generated code and won't change perfomance and code size if used properly. As with any template.

assembly does not change from the c++11 to 14 , the semantic did only .
Nonsence statement. Generated assembly depends only on compiler and might even change between compiler versions and its parameters. Changing semantics will change program behavior and will lead to different code being generated.
sure the assembly will change if you set different parameters for compilation.
I agree also that it could improve your code , if previously it was not used properly .
Topic archived. No new replies allowed.