Velocity Reviews > passing static 2D array to function - not fully working like I hoped for...

# passing static 2D array to function - not fully working like I hoped for...

someone
Guest
Posts: n/a

 12-29-2011
Hi all

Noob question:

-----------------------------------------------------------------------------
typedef float GLfloat; // float = GLfloat

void setBezierPoint(const double &x, const double &y, const double &z,
const int &P, GLfloat bezierCTRpts[][3])
{
bezierCTRpts[P][0] = (GLfloat)x;
bezierCTRpts[P][1] = (GLfloat)y;
bezierCTRpts[P][2] = (GLfloat)z;
}

void FindBezierControlPointsND(const int *N_kontur,
const double *cpp_X, const double *cpp_Y, GLfloat bezierData[]
[3])
{
// calculations...
// set xyz for point P=0 using 4th input parameter:
setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, 0, bezierData);

// set xyz for point P=3 using 4th input parameter:
setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, 3, bezierData);
}

int main(int argc, char** argv)
{
cout << "hi" << endl;
GLfloat bezierData[4][3] = {0};

// something
FindBezierControlPointsND( &N_kontur, Xval, Yval, bezierData);
}
-----------------------------------------------------------------------------

Explanation:

I have a static 2D array: bezierData[4][3], 4 points * xyz-coordinates
and I pass it to FindBezierControlPointsND with this call:

FindBezierControlPointsND( &N_kontur, Xval, Yval, bezierData);

and the function takes: GLfloat bezierData[][3] as input.
All is ok - the code works, however what I really wanted was to omit
the 4th input parameter (const int &P) so it looks like:

void setBezierPoint(const double &x, const double &y, const double &z,
GLfloat bezierCTRpts[][3]) // 4th input is GONE !
{
bezierCTRpts[0][0] = (GLfloat)x;
bezierCTRpts[0][1] = (GLfloat)y;
bezierCTRpts[0][2] = (GLfloat)z;
}

Then I wanted to set the xyz-values by a function call like:

- for P=0:
setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[0][0]);

- for P=3:
setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[3][0]);

This however doesn't work! I also tried to add "&" in front of
bezierData[3][0] etc... Error message is something like:

error: cannot convert ‘GLfloat* {aka float*}’ to ‘GLfloat* (*)[3] {aka
float* (*)[3]}’ for argument ‘4’ to ‘void setBezierPoint(const
double&, const double&, const double&, GLfloat* (*)[3])’

If you like/ask for it, perhaps I can make a minimal working example.
However, I hope one of you geniuses out there can spot my mistake
right on

THANKS!

Ben Bacarisse
Guest
Posts: n/a

 12-29-2011
someone <(E-Mail Removed)> writes:
<snip>
> -----------------------------------------------------------------------------
> typedef float GLfloat; // float = GLfloat
>
> void setBezierPoint(const double &x, const double &y, const double &z,
> const int &P, GLfloat bezierCTRpts[][3])

This is not C! Did you intend to remove the references? If you are
really writing C++ there may be much better ways to it.

> {
> bezierCTRpts[P][0] = (GLfloat)x;
> bezierCTRpts[P][1] = (GLfloat)y;
> bezierCTRpts[P][2] = (GLfloat)z;
> }
>
>
> void FindBezierControlPointsND(const int *N_kontur,
> const double *cpp_X, const double *cpp_Y, GLfloat bezierData[]
> [3])
> {
> // calculations...
> // set xyz for point P=0 using 4th input parameter:
> setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, 0, bezierData);
>
> // set xyz for point P=3 using 4th input parameter:
> setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, 3, bezierData);
> }
>
>
> int main(int argc, char** argv)
> {
> cout << "hi" << endl;
> GLfloat bezierData[4][3] = {0};
>
> // something
> FindBezierControlPointsND( &N_kontur, Xval, Yval, bezierData);
> }
> -----------------------------------------------------------------------------
>
> Explanation:
>
> I have a static 2D array: bezierData[4][3], 4 points * xyz-coordinates
> and I pass it to FindBezierControlPointsND with this call:
>
> FindBezierControlPointsND( &N_kontur, Xval, Yval, bezierData);
>
> and the function takes: GLfloat bezierData[][3] as input.
> All is ok - the code works, however what I really wanted was to omit
> the 4th input parameter (const int &P) so it looks like:
>
> void setBezierPoint(const double &x, const double &y, const double &z,
> GLfloat bezierCTRpts[][3]) // 4th input is GONE !

You need simply to pass a pointer to once bezier tripple, rather than to
(the start of) an array of them. Then, in the function, you drop the
first index.

void setBezierPoint(const double &x, const double &y, const double &z,
GLfloat bezierCTRpt[])
{
bezierCTRpt[0] = x;
bezierCTRpt[1] = y;
bezierCTRpt[2] = z;
}

(I make the name singular since there is now one point being passed).
Note that the casts are no needed -- they just clutter up the code in my
opinion.

> Then I wanted to set the xyz-values by a function call like:
>
> - for P=0:
> setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[0][0]);
>
> - for P=3:
> setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[3][0]);

Here you drop the second index or add and & operator:

setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[3]);
setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, &bezierData[3][0]);

> This however doesn't work! I also tried to add "&" in front of
> bezierData[3][0] etc... Error message is something like:

You were so close. Have a read of the C FAQ -- arrays are a little
fiddly: http://c-faq.com/

Post a follow up if you don't see why this works (or if I've got
the wrong end of the stick).

<snip>
--
Ben.

Jens Thoms Toerring
Guest
Posts: n/a

 12-29-2011
someone <(E-Mail Removed)> wrote:

Please note that your code is C++ while this is a C newsgroup.
It would be more prudent if you would post to comp.land.c++,
where the C++ experts are to be found. But since there's no
big difference here between C and C++ I'll try to come up
with a proposal:

> -----------------------------------------------------------------------------
> typedef float GLfloat; // float = GLfloat

> void setBezierPoint(const double &x, const double &y, const double &z,
> const int &P, GLfloat bezierCTRpts[][3])
> {
> bezierCTRpts[P][0] = (GLfloat)x;
> bezierCTRpts[P][1] = (GLfloat)y;
> bezierCTRpts[P][2] = (GLfloat)z;
> }

> void FindBezierControlPointsND(const int *N_kontur,
> const double *cpp_X, const double *cpp_Y, GLfloat bezierData[][3])
> {
> // calculations...
> // set xyz for point P=0 using 4th input parameter:
> setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, 0, bezierData);

> // set xyz for point P=3 using 4th input parameter:
> setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, 3, bezierData);
> }

> int main(int argc, char** argv)
> {
> cout << "hi" << endl;
> GLfloat bezierData[4][3] = {0};

> // something
> FindBezierControlPointsND( &N_kontur, Xval, Yval, bezierData);
> }
> -----------------------------------------------------------------------------

> Explanation:

> I have a static 2D array: bezierData[4][3], 4 points * xyz-coordinates
> and I pass it to FindBezierControlPointsND with this call:

> FindBezierControlPointsND( &N_kontur, Xval, Yval, bezierData);

> and the function takes: GLfloat bezierData[][3] as input.
> All is ok - the code works, however what I really wanted was to omit
> the 4th input parameter (const int &P) so it looks like:

> void setBezierPoint(const double &x, const double &y, const double &z,
> GLfloat bezierCTRpts[][3]) // 4th input is GONE !
> {
> bezierCTRpts[0][0] = (GLfloat)x;
> bezierCTRpts[0][1] = (GLfloat)y;
> bezierCTRpts[0][2] = (GLfloat)z;
> }

Why then not make it

void setBezierPoint(const double &x, const double &y, const double &z,
GLfloat bezierCTRpts[3])
{
bezierCTRpts[0] = (GLfloat)x;
bezierCTRpts[1] = (GLfloat)y;
bezierCTRpts[2] = (GLfloat)z;
}

Note that the casts to 'GLfloat' are rather likely unnecessary
- why did you put them in? I would recomend to use casts only
when they are really needed (and since you're doing C++ you
also should be using C++-style casts if you have a good reason
to use them.

> Then I wanted to set the xyz-values by a function call like:

> - for P=0:
> setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[0][0]);

> - for P=3:
> setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[3][0]);

With the modified signature of setBezierPoint() you know can
call it like

setBezierPoint( cpp_X[0], cpp_Y[0], 0.0, bezierData[0]);

setBezierPoint( cpp_X[0], cpp_Y[0], 0.0, bezierData[3]);

since setBezierPoint() now expects a simple array with 3 elements
and that's what you pass it that way.

Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)
\__________________________ http://toerring.de

Barry Schwarz
Guest
Posts: n/a

 12-29-2011
On Thu, 29 Dec 2011 09:11:08 -0800 (PST), someone
<(E-Mail Removed)> wrote:

>Hi all
>
>Noob question:
>
>-----------------------------------------------------------------------------
>typedef float GLfloat; // float = GLfloat
>
>void setBezierPoint(const double &x, const double &y, const double &z,
> const int &P, GLfloat bezierCTRpts[][3])

snip

You are looking fro comp.lang.c++. Down the hall, turn left at the
vending machine, third door on the right.

--
Remove del for email

someone
Guest
Posts: n/a

 12-29-2011
On Dec 29, 6:27*pm, Ben Bacarisse <(E-Mail Removed)> wrote:
> someone <(E-Mail Removed)> writes:
>
> <snip>
>
> > -----------------------------------------------------------------------------
> > typedef float GLfloat; // float = GLfloat

>
> > void setBezierPoint(const double &x, const double &y, const double &z,
> > * * * * * * * * * * const int &P, GLfloat bezierCTRpts[][3])

>
> This is not C! *Did you intend to remove the references? *If you are
> really writing C++ there may be much better ways to it.

I forgot that &(var) is C++, however I think that is the only thing I
forgot... I even added a typedef in the beginning to avoid someone
telling me that GLfloat "is not part of the C-standard, hence not a
question for this group"...

I am/was looking for the "C-answer", not a "C++-answer", so that's why
I thought it is better to post to here...

..........................

> > Explanation:

>
> > I have a static 2D array: bezierData[4][3], 4 points * xyz-coordinates
> > and I pass it to FindBezierControlPointsND with this call:

>
> > * FindBezierControlPointsND( &N_kontur, Xval, Yval, bezierData);

>
> > and the function takes: GLfloat bezierData[][3] as input.
> > All is ok - the code works, however what I really wanted was to omit
> > the 4th input parameter (const int &P) so it looks like:

>
> > void setBezierPoint(const double &x, const double &y, const double &z,
> > * * * * * * * * * * GLfloat bezierCTRpts[][3]) // 4th input is GONE !

>
> You need simply to pass a pointer to once bezier tripple, rather than to
> (the start of) an array of them. *Then, in the function, you drop the
> first index.

Aaah, thank you very much!

> * void setBezierPoint(const double &x, const double &y, const double &z,
> * * * * * * * * * * * GLfloat bezierCTRpt[])
> * {
> * * bezierCTRpt[0] = x;
> * * bezierCTRpt[1] = y;
> * * bezierCTRpt[2] = z;
> * }
>
> (I make the name singular since there is now one point being passed).
> Note that the casts are no needed -- they just clutter up the code in my
> opinion.

Thank you!

> > Then I wanted to set the xyz-values by a function call like:

>
> > - for P=0:
> > * setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[0][0]);

>
> > - for P=3:
> > * setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[3][0]);

>
> Here you drop the second index or add and & operator:
>
> * *setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[3]);
> * *setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, &bezierData[3][0]);

I see...

> > This however doesn't work! I also tried to add "&" in front of
> > bezierData[3][0] etc... Error message is something like:

>
> You were so close. *Have a read of the C FAQ -- arrays are a little
> fiddly:http://c-faq.com/

I tried to google quite some answers but couldn't find exactly this
little problem anywhere... Maybe q.6.18 from the C-faq should've
helped me.

In any case, it's great that there are people to help each other
around in here - thank you very much, Ben!

> Post a follow up if you don't see why this works (or if I've got
> the wrong end of the stick).

I get the idea now, thanks

someone
Guest
Posts: n/a

 12-29-2011
On Dec 29, 6:34*pm, (E-Mail Removed) (Jens Thoms Toerring) wrote:
> someone <(E-Mail Removed)> wrote:
>
> Please note that your code is C++ while this is a C newsgroup.

Maybe 1% C++ and 99% C, ok.

> It would be more prudent if you would post to comp.land.c++,
> where the C++ experts are to be found. But since there's no

No, I don't think so.

> big difference here between C and C++ I'll try to come up
> with a proposal:

.................

> > Explanation:
> > I have a static 2D array: bezierData[4][3], 4 points * xyz-coordinates
> > and I pass it to FindBezierControlPointsND with this call:
> > * FindBezierControlPointsND( &N_kontur, Xval, Yval, bezierData);
> > and the function takes: GLfloat bezierData[][3] as input.
> > All is ok - the code works, however what I really wanted was to omit
> > the 4th input parameter (const int &P) so it looks like:
> > void setBezierPoint(const double &x, const double &y, const double &z,
> > * * * * * * * * * * GLfloat bezierCTRpts[][3]) // 4th input is GONE !
> > {
> > * bezierCTRpts[0][0] = (GLfloat)x;
> > * bezierCTRpts[0][1] = (GLfloat)y;
> > * bezierCTRpts[0][2] = (GLfloat)z;
> > }

>
> Why then not make it
>
> void setBezierPoint(const double &x, const double &y, const double &z,
> * * * * * * * * * *GLfloat bezierCTRpts[3])
> {
> * bezierCTRpts[0] = (GLfloat)x;
> * bezierCTRpts[1] = (GLfloat)y;
> * bezierCTRpts[2] = (GLfloat)z;
>
> }

Thank you very much.

> Note that the casts to 'GLfloat' are rather likely unnecessary
> - why did you put them in? I would recomend to use casts only

Actually I cast double -> float, so I make the intermediate
calculations using double precision, but when it comes to actually
storing the data, I save it as a float (less precision). Normally I
would be doing everything with double precision...

Of some reason, floats seem to be widely used with opengl... Don' ask
me why - I don't know. That's why I cast. I could also cast before
calling the function, of course...

> when they are really needed (and since you're doing C++ you
> also should be using C++-style casts if you have a good reason
> to use them.

I don't see why, if it works and apparently it does work out fine with
C?

> > Then I wanted to set the xyz-values by a function call like:
> > - for P=0:
> > * setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[0][0]);
> > - for P=3:
> > * setBezierPoint(cpp_X[0], cpp_Y[0], 0.0, bezierData[3][0]);

>
> With the modified signature of setBezierPoint() you know can
> call it like
>
> * * setBezierPoint( cpp_X[0], cpp_Y[0], 0.0, bezierData[0]);
>
> * * setBezierPoint( cpp_X[0], cpp_Y[0], 0.0, bezierData[3]);
>
> since setBezierPoint() now expects a simple array with 3 elements
> and that's what you pass it that way.

That's great Jens. Thank you very much. Appreciate your help and
time...

someone
Guest
Posts: n/a

 12-29-2011
On Dec 29, 6:49*pm, Barry Schwarz <(E-Mail Removed)> wrote:
> On Thu, 29 Dec 2011 09:11:08 -0800 (PST), someone
>
> <(E-Mail Removed)> wrote:
> >Hi all

>
> >Noob question:

>
> >-----------------------------------------------------------------------------
> >typedef float GLfloat; // float = GLfloat

>
> >void setBezierPoint(const double &x, const double &y, const double &z,
> > * * * * * * * * * *const int &P, GLfloat bezierCTRpts[][3])

>
> snip
>
> You are looking fro comp.lang.c++.

No I'm not.

Seebs
Guest
Posts: n/a

 12-29-2011
On 2011-12-29, someone <(E-Mail Removed)> wrote:
>> You are looking fro comp.lang.c++.

> No I'm not.

I'm curious as to why you say this. Your code is obviously C++. Nothing
similar to it has ever been part of C.

Granted that a similar question could apply to C, the mere fact that you're
using references means that the rules for what you're doing are certainly
going to be different.

So the question is: Why *aren't* you looking for a C++ group? Do you think
that they would be unable to answer your question? If so, why?

-s
--
Copyright 2011, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Jens Thoms Toerring
Guest
Posts: n/a

 12-29-2011
someone <(E-Mail Removed)> wrote:
> On Dec 29, 6:34Â*pm, (E-Mail Removed) (Jens Thoms Toerring) wrote:
> > someone <(E-Mail Removed)> wrote:
> >
> > Please note that your code is C++ while this is a C newsgroup.

> Maybe 1% C++ and 99% C, ok.

Well, there are sume subtle differences between C and C++
and when you write C++ (i.e. use a C++ compiler, your program
won't compile with a C compiler) then it's typically better
to ask in the correct group - it may safe you a lot of time
and grieve. And sometimes there are also more elegant so-
lutions to a problem in C++.

> > Note that the casts to 'GLfloat' are rather likely unnecessary
> > - why did you put them in? I would recomend to use casts only

> Actually I cast double -> float, so I make the intermediate
> calculations using double precision, but when it comes to actually
> storing the data, I save it as a float (less precision). Normally I
> would be doing everything with double precision...

All calculations are done in double anyway (even if you
use floats - and on quite a number of architectures even
with an even wider representation than double, i.e. on
x86 you often have 64 bit doubles but computation are all
done with 80 bit) and if you assign to a float the value
will be converted to a float without any cast.

> Of some reason, floats seem to be widely used with opengl...

Probably because the results don't need a high precision (does
it matter if a pixel is shown at position 231.122387267423 or
231.122387267424?) and floats often take only half as much
space as doubles to store.
Regards, Jens
--
\ Jens Thoms Toerring ___ (E-Mail Removed)
\__________________________ http://toerring.de

Keith Thompson
Guest
Posts: n/a

 12-29-2011
someone <(E-Mail Removed)> writes:
> On Dec 29, 6:34Â*pm, (E-Mail Removed) (Jens Thoms Toerring) wrote:
>> someone <(E-Mail Removed)> wrote:
>>
>> Please note that your code is C++ while this is a C newsgroup.

>
> Maybe 1% C++ and 99% C, ok.

There's a term for code that's 1% CZ++ and 99% C. We call it "C++".

There are at least 2 C++-specific things in your code: the parameters of
setBezierPoint are C++ references, and you use "cout << ..." in main().

And even if those are corrected, you have no declaration for N_kontur,
Xval, or Yval.

It's not a *huge* deal, but for future reference it's best to post
straight C code here. Compile it with a C compiler and copy-and-paste
the exact code that you compiled. Otherwise, it can be difficult to
tell whether your problems are C++-specific and/or whether they're
related to errors you made when you re-typed the code.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"