1

Here in f() I accept array to be of maximum size 4 but it still runs fine when I pass an array of size greater than 4(here 10), I know arrays in c++ are passed as pointers by default but than when is this method of passing array useful?

#include<iostream>

using namespace std;

void f(int a[4]){
    for(int i  = 0;i < 3;i++){
        a[i] += 10;
    }
}

int main(){
    int a[10];
    for(int i = 0;i < 10;i++)
        a[i] = i;
    f(a);
    for(int i =0 ;i < 10;i++){
        cout<<a[i]<<" ";
    }
    cout<<"\n";
    return 0;
}

output: 10 11 12 3 4 5 6 7 8 9

8
  • Use std::array or std::vector instead Commented May 2, 2019 at 14:05
  • That is the curse of C arrays. You cannot put them in function parameters or return them. You have to find some workaround of using a pointer or reference to the array or stuffing the array in a struct (which is what std::array is). Commented May 2, 2019 at 14:06
  • I just wanted to know why is this method of accepting array in c++ used Commented May 2, 2019 at 14:06
  • "why is this method of accepting array in c++ used" for compatibility with C Commented May 2, 2019 at 14:07
  • I heard the reason is that in early C, wanting to pass an array by value was unthinkable and most definitely a performance bug. So they decided to silently fix your performance bug by turning the array into a pointer. Commented May 2, 2019 at 14:09

3 Answers 3

4

I know arrays in c++ are passed as pointers by default

Correct.

This:

void foo(int a[4])

is literally rewritten to this:

void foo(int* a)

… and then when you call the function your array's name decays to the pointer, matching the rewritten/"real" argument type.

So you're not really passing an array at all.

When is this method of passing array useful?

Never.

This is a shameful oddity inherited from C. One might argue that the [4] is a useful hint to the developer that the pointed-to array "should" have four elements, but modern wisdom is that this is just unnecessarily and dangerously misleading.

Better alternatives include:

  • Pointer/size pair (two arguments): this is not less dangerous per se, but at least it does not lie about the type and lull you into a false sense of security!
  • Array by reference: lovely jubbly, but less flexible
  • std::array<int, 4> (by reference): as above, but neater
Sign up to request clarification or add additional context in comments.

2 Comments

Or switch to std::vector instead of an array - this is almost always my first suggestion.
@MartinBonner Probably overkill for four ints but worth considering if you need the resizable storage (if not, there's really no reason to prefer vector over array)
2

Either make f() more restrictive as shown by @songyuanyao or consider using a C++ std::array instead:

#include <iostream>
#include <array>

// make an alias for the array you'd like to accept
using myarray_t = std::array<int, 4>;

// accept the array by reference
void f(myarray_t& a) {
    // use a range based for loop to access elements by reference
    for(int& a_i : a) a_i += 10;
}

int main() {
    // declare your array
    myarray_t a;
    for(size_t i = 0; i < a.size(); ++i) a[i] = static_cast<int>(i);
    f(a);
    // and you can use a range based for loop to extract by value too 
    for(int a__i : a)
        std::cout << a_i << " ";

    std::cout << "\n";
    return 0;
}

Comments

2

If you want to impose restrictions on the size of the array passed in, you can change to pass-by-reference.

void f(int (&a)[4]){
    for(int i  = 0;i < 3;i++){
        a[i] += 10;
    }
}

void f(int a[4]) is same as void f(int* a); that means you can pass the array with any size which will decay to pointer (i.e. int*) when being passed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.