Array parameter in function prototype not able to receive default value.

Started by
16 comments, last by King Mir 10 years, 1 month ago

I initially thought it was a constant pointer, but it seems I can change the address it points to, hence it is not really a constant pointer.

Intel Core 2 Quad CPU Q6600, 2.4 GHz. 3GB RAM. ATI Radeon HD 3400.
Advertisement

There are multiple places you can put the const, each with different meanings.

"const int * x" means that x is a pointer to constant integers. You can modify the pointer, but you cannot modify what it points to.

"int * const x" means that x is a constant pointer to integers. You cannot modify the pointer, but you can modify what it points to.

"const int * const x" means x is a constant pointer to constant integers. You cannot modify the pointer, and you cannot modify what it points to.

int foo(int);
inline int foo() { return foo(42); }

I think you meant:


int foo();
inline int foo() { return foo(42); }

Otherwise you would be declaring the function for another overloaded implementation.

Nevermind, that was your intention(to declare another function to deal with the function definition with simulated default value.)

Intel Core 2 Quad CPU Q6600, 2.4 GHz. 3GB RAM. ATI Radeon HD 3400.

int foo(int);
inline int foo() { return foo(42); }

I think you meant:


int foo();
inline int foo() { return foo(42); }

Otherwise you would be declaring the function for another overloaded implementation.

No, what I had down was correct.

When you provide a default parameter, you are providing a function that takes a parameter. That would be int foo(int). Your function is written with a parameter.

If you don't provide a parameter you have an automatically-generated overload without the parameter, that would be int foo(), which is a simple function to call the actual function with that default parameter.

Try this:
void VectorStuff(const float (&p)[3]={52.0f,53.1f,54.2f});
The problem with the OP is that you can't initialize a pointer with the address of a temporary. Nor can you pass an array by value, using any syntax (except std::array). You can however initialize a const reference with a temporary. You can also use an rvalue reference if you want the array to be mutable.

Note that passing an array like this has one notable downside: you can't dynamically allocate an array like this. You'd have to reinterpret_cast a float * to an float (*) [3]. That's why using std::array is a better solution.

EDIT: The other problem is, you're not using a compiler configured to support C++11 initializer lists, so you're getting a syntax error instead of a semantic error.

There are multiple places you can put the const, each with different meanings.

"const int * x" means that x is a pointer to constant integers. You can modify the pointer, but you cannot modify what it points to.

"int * const x" means that x is a constant pointer to integers. You cannot modify the pointer, but you can modify what it points to.

"const int * const x" means x is a constant pointer to constant integers. You cannot modify the pointer, and you cannot modify what it points to.

What I meant with:

Why is a C array able to receive the address of another C array as an initializer?

is that it is not legal syntax to initialize arrays with other arrays or pointers:


int array1[3] = {4,5,6};
int array2[3] = array1; // NICHT!
Intel Core 2 Quad CPU Q6600, 2.4 GHz. 3GB RAM. ATI Radeon HD 3400.


What I meant with:

Why is a C array able to receive the address of another C array as an initializer?

is that it is not legal syntax to initialize arrays with other arrays or pointers:

int array1[3] = {4,5,6};
int array2[3] = array1; // NICHT!
Ah, that is mostly for historical reasons.

The first one allows the compiler to do some fun trick with data. If the array is constant it is possible for the array to really just be pointer to data inside the program and not allocate any memory at all. If it is non-constant then depending on how it is used will probably need to make a copy of the data, but that is just a memcpy() command.

The second one, however, doesn't work that way. It needs to point array2 to a block of memory somewhere, but the compiler doesn't know exactly where. It could possibly create it on the stack, but then there are some questions about copying it over in such a way that avoids all possibility of aliasing or other problems. While allowing it in some cases like the one you presented are fairly easy, you can construct cases that are very hard or even impossible to figure out at compile time. Things like variable length arrays, partial initialization and incomplete types further complicate the matter.
Yeah, back in the early days of C, it was decided that it never makes sense to pass an arrays by value. So for uniformity arrays use value syntax just like everything else, but actually are passed as pointers to the underlying type. And you can't assign arrays, or initialize array with other arrays, for similar reasons -- that would be using an array as a value. It's too much implicit logic built to build in to the language.

Today, all those reason are out of date, so std::array exists to make arrays uniform with other types.

This topic is closed to new replies.

Advertisement