Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


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


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
17 replies to this topic

#1 gasto   Members   -  Reputation: 272

Like
0Likes
Like

Posted 28 February 2014 - 05:07 PM

void VectorStuff(float p[3]={52.0f,53.1f,54.2f}); // NICHT!

build output:

syntax error : missing ')' before '{'

Functions in C++ are not able to receive default parameters for arrays because It is not really an array parameter, it is a const pointer(like in C.), ergo attempting to assign such parameter with default values on the prototype of the function will confuse the compiler, it will lead the compiler to believe one is attempting to define an array and initialize it in a function parameter list.

 

Correct me if I am wrong.


Edited by gasto, 28 February 2014 - 05:17 PM.

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

Sponsor:

#2 Paradigm Shifter   Crossbones+   -  Reputation: 5410

Like
0Likes
Like

Posted 28 February 2014 - 05:11 PM

I'm sure there is a question in there waiting to get out.

 

You could pass the address of a static/global "DefaultParameterArray" if you liked as a default argument. Not sure how useful that would be.


"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#3 gasto   Members   -  Reputation: 272

Like
0Likes
Like

Posted 28 February 2014 - 05:16 PM

I'm sure there is a question in there waiting to get out.

 

You could pass the address of a static/global "DefaultParameterArray" if you liked as a default argument. Not sure how useful that would be.

 

Could you write the pseudo code or C++ code for it? I am not sure what you mean by that.


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

#4 Paradigm Shifter   Crossbones+   -  Reputation: 5410

Like
0Likes
Like

Posted 28 February 2014 - 05:20 PM

int g_DefaultArray[] = { 1, 2, 3, 4 };

 

void MyFunc(int* arr = g_DefaultArray);

 

EDIT: Problems there with no passing the size. Use a vector instead.


Edited by Paradigm Shifter, 28 February 2014 - 05:20 PM.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#5 Brother Bob   Moderators   -  Reputation: 8452

Like
2Likes
Like

Posted 28 February 2014 - 05:39 PM

int g_DefaultArray[] = { 1, 2, 3, 4 };

 

void MyFunc(int* arr = g_DefaultArray);

 

EDIT: Problems there with no passing the size. Use a vector instead.

If you want to restrict the argument to an array of three floats, you can change the parameter type to take a reference to an array instead of a pointer.

void VectorStuff(float (&p)[3] = g_DefaultArray)

Although, the array has to be three elements instead of four, as implied from OP's first post. The size of the array passed is enforced at compile time.



#6 Paradigm Shifter   Crossbones+   -  Reputation: 5410

Like
0Likes
Like

Posted 28 February 2014 - 05:42 PM

I wrote my reply before Ninja edits added some code to make the question meaningful ;)


"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#7 SeanMiddleditch   Members   -  Reputation: 6432

Like
2Likes
Like

Posted 28 February 2014 - 08:33 PM

Using C++11:

#include <array>

void VectorStuff(std::array<float, 3> const& p = {1,2,3});


#8 frob   Moderators   -  Reputation: 22246

Like
1Likes
Like

Posted 28 February 2014 - 10:00 PM

Based on your earlier and revised post, it looks like you are trying to do many things at once. As a general rule, do one thing at a time. You are creating an array, initialized to specific values. Do that in one line. You are calling a function with an array as a parameter. Do that all at once.


You could also be asking about two other kinds of problems.

If you are talking about default parameters, they are not really anything magical.

When you write a function with a default parameter, like so:

int foo( int param = 42 );

what the compiler really does is make a stub function for you that automatically gets inlined, like so:

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

You can just as easily do that yourself, and in many pieces of professional code default parameters are forbidden and must be made explicitly by the programmer.

In your case, perhaps:

void VectorStuff( float* ); /* You probably want to make that "const float *" unless you intend to modify values */
inline void VectorStuff() { float p[3]={52.0f,53.1f,54.2f}; VectorStuff(p); )



Or your question might be referring to an unspecified number of parameters, there is something that comes from the ancient past of the language to handle that. It is not recommended because it is unsafe safe, but it might do what you are asking. There is a thing called variadic functions that allows you to pass whatever parameters you want.

Common examples are the printf and scanf family. The declaration of the function is simple enough: int printf ( const char * format, ... ); With that signature you are required to pass a string, and then you can pass zero or more additional parameters. You can then access the parameters passed within the "... "by using the va_xxx family of utilities. It is extremely unsafe for many reasons. Only certain types of data can be passed and there are automatic conversions that take place if your types don't match. It is up to the programmers to ensure the code handles the data types correctly, and there is no automatic mechanism in the language to detect the data type that was passed. If you do it wrong your program will behave badly, crash, or worse. Even though it is unsafe, it is something the language provides and if you are careful can solve some real programming problems.

There is similar functionality in languages like Java and C# that converts the arguments into an array of 'object' type, that is, the base class from which all classes are derived. These languages provide ways to determine the actual type of the data, so their solution is much safer but comes with its own set of hidden costs.

Edited by frob, 28 February 2014 - 10:15 PM.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I write about assorted stuff.


#9 gasto   Members   -  Reputation: 272

Like
0Likes
Like

Posted 01 March 2014 - 11:38 AM

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

 

float g_array[3]={77.0f,88.0f,99.0f};
 
void VecStuff(float p[3]=g_array);

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

#10 Brother Bob   Moderators   -  Reputation: 8452

Like
0Likes
Like

Posted 01 March 2014 - 11:43 AM

The argument p in your function is a pointer, and it's default value is to point to the array. The array syntax decays into a pointer, so your function prototype is actually:

void VecStuff(float *p=g_array);


#11 gasto   Members   -  Reputation: 272

Like
0Likes
Like

Posted 01 March 2014 - 01:16 PM

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.

#12 frob   Moderators   -  Reputation: 22246

Like
0Likes
Like

Posted 01 March 2014 - 01:52 PM

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.


Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I write about assorted stuff.


#13 gasto   Members   -  Reputation: 272

Like
0Likes
Like

Posted 01 March 2014 - 03:15 PM

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.)


Edited by gasto, 01 March 2014 - 03:43 PM.

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

#14 frob   Moderators   -  Reputation: 22246

Like
0Likes
Like

Posted 01 March 2014 - 03:41 PM

 

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.


Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I write about assorted stuff.


#15 King Mir   Members   -  Reputation: 2032

Like
0Likes
Like

Posted 01 March 2014 - 04:16 PM

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.

Edited by King Mir, 01 March 2014 - 04:22 PM.


#16 gasto   Members   -  Reputation: 272

Like
0Likes
Like

Posted 01 March 2014 - 05:06 PM

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!

Edited by gasto, 01 March 2014 - 05:06 PM.

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

#17 frob   Moderators   -  Reputation: 22246

Like
0Likes
Like

Posted 01 March 2014 - 06:53 PM

 
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.

Check out my book, Game Development with Unity, aimed at beginners who want to build fun games fast.

Also check out my personal website at bryanwagstaff.com, where I write about assorted stuff.


#18 King Mir   Members   -  Reputation: 2032

Like
0Likes
Like

Posted 01 March 2014 - 07:36 PM

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.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS