Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

best way to pass a multiple dimension variable to a method

38 views
Skip to first unread message

Lynn McGuire

unread,
Dec 21, 2022, 3:38:01 PM12/21/22
to
What is the best way to pass a multiple dimension variable to a method
in C++ ?

For instance, in C you could do the following:

double xyz [5] [2] [14];
...
amethod (xyz, ...);

Thanks,
Lynn

Richard Damon

unread,
Dec 21, 2022, 5:10:20 PM12/21/22
to
You can do the same thing in C++ with a primative array, or
you can define a container that acts like a multidimensional object, or
you can use something like a vector of vectors (or array object of array
objects)

Lynn McGuire

unread,
Dec 21, 2022, 5:18:46 PM12/21/22
to

Öö Tiib

unread,
Dec 21, 2022, 9:03:47 PM12/21/22
to
If the xyz is raw fixed dimension array then passing by reference is best as it
is not losing any dimension information.
void amethod(double (&xyz)[5][2][14], ...)

About "multiple dimension variable" it depends on properties and usage.
What dimensions you want to be dynamic if any and with what algorithms
you want to process it. With little object of 140 doubles the usage does not
matter but if it is far bigger than 500 doubles then cache-friendliness of data
layout for processing can show noticeable differences.

Ben Bacarisse

unread,
Dec 21, 2022, 10:02:32 PM12/21/22
to
Lynn McGuire <lynnmc...@gmail.com> writes:

> On 12/21/2022 2:37 PM, Lynn McGuire wrote:
>> What is the best way to pass a multiple dimension variable to a method in C++ ?
>> For instance, in C you could do the following:
>>     double xyz [5] [2] [14];
>>     ...
>>     amethod (xyz, ...);

Best is always going to depend on lost of as yet unspecified factors.
Are the sizes (other than the "top-level" one) always know at compile
time? Are they always the same?
That hardly scratches the surface!

> and
>
> https://stackoverflow.com/questions/8767166/passing-a-2d-array-to-a-c-function

C has variably modified types which means you can pass run-time array
sizes to a C function. C++ does not have this feature, but then that
page includes some C++ and does not use variably modified types (as far
as I could see).

You probably need to say more about your constraints to get better advice.

--
Ben.

Paavo Helde

unread,
Dec 22, 2022, 2:08:09 AM12/22/22
to
This C approach only really works as long as the dimensions are known at
compile time and the arrays are small (larger arrays won't fit on stack).

In C++, suggesting a custom class containing a plain std::vector for
data storage and separate dimension info, providing some kind of 3D
interface on top of that.

Details depend on whether you prefer simple nice interfaces over speed,
what are your typical dimensions, and what are your typical operations.

In case you are interested in nice interfaces, one can provide nice
operator[] overloads with proxies, so that you can access elements of
your array via nice arr[x][y][z], or technically simpler arr.Elem(x, y, z).

In case you are interested in performance, one needs to avoid arithmetic
or multiple indirections when accessing single elements, and one needs
to take care about memory locality. This in general means that the 3D
abstraction becomes leaky; the algorithm working on the data would need
to take out pointers to the whole linear array, or to the most tightly
packed linear stretches, and iterate over them by itself. A single pixel
access function like arr[x][y][z] or arr.Elem(x, y, z) would be pretty
useless.

No doubt there are already a myriad of multidimensional array libraries
out there, but as the right solution depends on your needs, data, and
usage, finding a suitable library might be more complicated than writing
your own class suited to your needs.



Lynn McGuire

unread,
Dec 22, 2022, 3:02:02 AM12/22/22
to
I don't know if the array sizes are always known at compile time. I
suspect that they are but I am far from sure.

I am moving a 750,000 line F77 / C calculation engine to C++ using a
modified version of F2C. F2C converts all multiple dimension arrays to
single dimension arrays. Sometimes I convert them back. Still a few
unknowns to work out.

Thanks,
Lynn

Öö Tiib

unread,
Dec 22, 2022, 3:25:59 AM12/22/22
to
On such cases where we are transpiling and rearranging handling of
arrays it is worth to write some tests to verify correctness of result and
also to profile its efficiency.

Issue is that Fortran keeps arrays always in column-major order C keeps
arrays always in row-major order. Code of either can be optimised to take
that into account.

In C++ it is possible to design classes agnostic about that ordering. We
can see that in several linear algebra libraries. Matrices choose ordering
based on what was most efficient to get from algorithm and then
choose algorithms based on ordering what is most efficient to process
and that all is hidden behind scenes so user should not care.

Ben Bacarisse

unread,
Dec 22, 2022, 7:14:16 AM12/22/22
to
You may better off just passing a pointer to the correct amount of space
and doing the indexing "by hand".

Do you ever need slices like column of row arrays? That might be
another reason to do the index arithmetic yourself.

--
Ben.

David Brown

unread,
Dec 22, 2022, 9:05:09 AM12/22/22
to
On 22/12/2022 03:03, Öö Tiib wrote:
> On Thursday, 22 December 2022 at 00:18:46 UTC+2, Lynn McGuire wrote:
>> On 12/21/2022 2:37 PM, Lynn McGuire wrote:
>>> What is the best way to pass a multiple dimension variable to a method
>>> in C++ ?
>>>
>>> For instance, in C you could do the following:
>>>
>>> double xyz [5] [2] [14];
>>> ...
>>> amethod (xyz, ...);
>>>
>>> Thanks,
>>> Lynn
>> I am looking at
>> https://www.educba.com/3d-arrays-in-c-plus-plus/
>> and
>>
>> https://stackoverflow.com/questions/8767166/passing-a-2d-array-to-a-c-function
>
> If the xyz is raw fixed dimension array then passing by reference is best as it
> is not losing any dimension information.
> void amethod(double (&xyz)[5][2][14], ...)
>

I would suggest that any time you have fixed size arrays, you are better
off using std::array<>. Then the size is clearly fixed in the type, and
there are no circumstances in which it "disappears" or the array decays
into a pointer. (As Ben pointed out in another thread, it's not always
easy to tell when this happens.) And you have container-style methods
for the array if you want them, while all the time keeping the
efficiency of a plain C array.

It can be a little ugly to use std::array's of std::arrays, so a
wrapping class might help. Or a template using :

template <class T, size_t x, size_t y, size_t z>
using array3d = std::array<std::array<std::array<T, z>, y>, x>;

array3d<double, 5, 2, 14> xyz;


Lynn McGuire

unread,
Dec 22, 2022, 11:10:30 PM12/22/22
to
On 12/21/2022 2:37 PM, Lynn McGuire wrote:
Thanks to all ! I am slowly puzzling my way through this.

Thanks,
Lynn


Lynn McGuire

unread,
Dec 22, 2022, 11:23:18 PM12/22/22
to
On 12/21/2022 2:37 PM, Lynn McGuire wrote:
BTW, I am also looking at this:

https://stackoverflow.com/questions/13326021/how-to-pass-a-3d-array-as-a-parameter-to-function-c-also-do-global-variables

Thanks,
Lynn

0 new messages