0

I am designing a C function interface which involves a 2d array. The problem is, row dimension is constant, and column one should be user defined.

#define ROWS (65)
void init(int columns, float array[ROWS?][columns?])
{
   ...
}

void main()
{
    float array1[ROWS][30]; 
    float array2[ROWS][50]; 
    init(30, array1); 
    init(50, array2); 
} 

How do I design an interface to be able to pass this kind of array down to function?

p.s.
Can't do it the other way around, where columns would be constant, because must use some 3rd pary libraries that want it this way.

9
  • Are you limited to a certain standard of C? Commented May 4, 2018 at 10:53
  • Yes, limited to C99. Commented May 4, 2018 at 10:54
  • For C11 and C99 you can just declare it as void init(int columns, float array[ROWS][columns]). Commented May 4, 2018 at 10:55
  • @haccks #define ROWS (65) is fine, although the parentheses are redundant if the macro is just being used as a constant. Commented May 4, 2018 at 11:01
  • "to pass this kind of array down to function?", listen me carefully, you can't pass any array of any kind to any function in C, this is simply impossible it's will always be a pointer. Commented May 4, 2018 at 11:01

2 Answers 2

4

Simply do as you wrote in your example

void init (size_t rows, size_t columns, float array[rows][columns])

Then you can pass compile-time constants or run-time variables to the function as you please. You'll also need to have C compiler from the current millennium (C99 or later).

Sign up to request clarification or add additional context in comments.

2 Comments

mingw32-g++.exe gives error: use of parameter outside function body before ']' token. What about C++ compilers?
@Danijel C++ does not have VLA. This is tagged C so I gave a C answer. Compile the code with a C compiler.
3

You mentioned in a comment. So it shouldn't be too difficult to approximate what you want. In fact, you are almost there yourself. It can look like this:

#define ROWS 65
void init(int columns, float array[static ROWS][columns])
{

}

Now array is of a variably modified type, and columns is user defined. static ROWS means callers must pass in an array of at least 65 rows, or undefined behavior will ensue. That's pretty much as close to forcing them to pass 65 as you can.

4 Comments

Actually the static keyword here does nothing in practice, since the array will get adjusted to an array pointer before arguments are checked. To achieve some manner of increased type safety, neither your solution nor mine will do, but one has to make the parameter float (*array)[rows][columns].
@Lundin - I have seen instances of Clang warning about improper arrays sizes when static is used, though for the life of me I can't recall the exact compiler switch. There is also the idiom of using [static 1] to better signal no null check will be perform, but YMMV. float (*array)[rows][columns] is just uncomfortable on the caller. I personally think the OP may want to avoid that if they are writing a library. But for sure, that's the way to go to force the type checking.
I suppose it isn't really specified when exactly the "array adjustment" of function parameters takes place. In gcc, static is completely superfluous unless used on one of the dimensions to the right, that don't get adjusted. It always seemed like a superfluous feature to me, much like [*] in function declarations.
@Lundin - I guess it's one of those features which the committee hoped implementations will use to improve diagnostics, when in practice they just don't bother. A global QoI issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.