Adding const keyword to an array passed as a parameter to function

前端 未结 5 1018
死守一世寂寞
死守一世寂寞 2021-02-07 07:17

Is there any way that I can add const keyword to an array passed as a parameter to function:

void foo(char arr_arg[])

If I place <

相关标签:
5条回答
  • 2021-02-07 07:51

    There's several ways in C++, but none are quite what you seem to be expecting.

    //typedef has a very clear intent
    typedef char* array;
    void f0(const array a) {}
    
    //switch to pointers to sidestep the problem
    void f1(char* const a) {}
    
    //references are inherently const
    //can't take pointers, but guarantees the size, sometimes nice
    //this version obviously doesn't work in C
    template<int n>
    void f2(char (&a)[n]) {}
    

    http://ideone.com/4LvYT

    0 讨论(0)
  • 2021-02-07 07:53

    In C you have to put const between the [], however strange that might look to an unprepared person

    void foo(char arr_arg[const]);
    

    This is "new" C99-specific syntax. In C89/90 or C++ there no way to do it with "array" syntax, so you have to switch to the equivalent "pointer" syntax, as suggested in David's answer.

    0 讨论(0)
  • 2021-02-07 07:54

    Yes, in C this is possible since C99:

    void foo(char ptr_arg[const]);
    

    is valid syntax and equivalent to

    void foo(char *const ptr_arg);
    

    More generally the [] may contain any type qualifier, static and an integer expression. But

    The optional type qualifiers and the keyword static shall appear only in a declaration of a function parameter with an array type, and then only in the outermost array type derivation.

    that is for the dimension that is equivalent to the pointer declaration.

    0 讨论(0)
  • 2021-02-07 07:55

    The first thing is that in your particular signature, the argument is transformed by the compiler into a pointer, so what you have is:

    void foo( char * arg );
    

    Now, there are two entities that can be made const in that signature: the pointer and the pointed type. To make the pointed type can be made const in two different yet equivalent ways [*]:

    void foo( const char * arg );
    void foo( char const * arg );
    

    The pointer could be made const with the syntax:

    void foo( char * const arg );
    

    But note that in a function signature, in the same way that char arg[] is transformed into a pointer char *arg, the top level qualifier is discarded. So from the point of view of the declaration, these two are equivalent:

    void foo( char * const arg );
    void foo( char *       arg );
    

    In the definition, the top level const can be use to instruct the compiler that the argument pointer (by value) should not be changed within the function, and it will detect if you attempt to reset the pointer to a different location. But, if only the pointer is const, then the compiler will gladly let you modify the pointed memory. If you don't want the function to change the contents of the array, then you should opt for one of the first two signatures.

    [*] I tend to prefer the char const * format, as it provides a consistent way of reading types: from right to left it reads: a non-const pointer to a const char. Additionally it is simpler to reason about typedef-ed types (by performing direct substitution in the expression). Given typedef char* char_p;, const char_p and char_p const are both equivalent to char * const and different from const char *. By consistently using const on the right you can just blindly substitute the typedef and read the type without having to reason.

    0 讨论(0)
  • 2021-02-07 08:00

    For C++, Mooing Duck's answer using the template is the most straight forward.

    If you have C code that is calling a C interface implemented in C++, you are stuck with converting the argument into a pointer argument instead, and making that const

    If you were to use Boost's array instead of using C arrays directly, then you would be able to make that const, although it would also be a template function:

    template <unsigned N>
    void foo (Boost::array<char, N> const & arg) {}
    

    The advantage of Boost::array is that it gives you the ability to do a light weight allocation of an array off the stack, but be able to fully use STL algorithms that depend upon traits in the container.

    0 讨论(0)
提交回复
热议问题