Why do C and C++ compilers allow array lengths in function signatures when they're never enforced?

后端 未结 10 1414
终归单人心
终归单人心 2020-11-22 06:59

This is what I found during my learning period:

#include
using namespace std;
int dis(char a[1])
{
    int length = strlen(a);
    char c = a         


        
10条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-22 07:36

    The problem and how to overcome it in C++

    The problem has been explained extensively by pat and Matt. The compiler is basically ignoring the first dimension of the array's size effectively ignoring the size of the passed argument.

    In C++, on the other hand, you can easily overcome this limitation in two ways:

    • using references
    • using std::array (since C++11)

    References

    If your function is only trying to read or modify an existing array (not copying it) you can easily use references.

    For example, let's assume you want to have a function that resets an array of ten ints setting every element to 0. You can easily do that by using the following function signature:

    void reset(int (&array)[10]) { ... }
    

    Not only this will work just fine, but it will also enforce the dimension of the array.

    You can also make use of templates to make the above code generic:

    template
    void reset(Type (&array)[N]) { ... }
    

    And finally you can take advantage of const correctness. Let's consider a function that prints an array of 10 elements:

    void show(const int (&array)[10]) { ... }
    

    By applying the const qualifier we are preventing possible modifications.


    The standard library class for arrays

    If you consider the above syntax both ugly and unnecessary, as I do, we can throw it in the can and use std::array instead (since C++11).

    Here's the refactored code:

    void reset(std::array& array) { ... }
    void show(std::array const& array) { ... }
    

    Isn't it wonderful? Not to mention that the generic code trick I've taught you earlier, still works:

    template
    void reset(std::array& array) { ... }
    
    template
    void show(const std::array& array) { ... }
    

    Not only that, but you get copy and move semantic for free. :)

    void copy(std::array array) {
        // a copy of the original passed array 
        // is made and can be dealt with indipendently
        // from the original
    }
    

    So, what are you waiting for? Go use std::array.

提交回复
热议问题