2

I am converting some C-code to C++ so that I can use some more advanced C++ features. However, in one particular function I have a problem because the syntax is allowed in C, but not C++. Specifically, the following is valid C-code, but not C++:

void get_xu_col(int i_start,
                int n,
                double x[n],
                int n_x,
                int n_u,
                int n_col,
                double xu_col[n_col][n_x + n_u]) {
    ...
}

Thanks to the answers here, I understand that this is valid C, but not C++. However, I want to emulate this behavior in C++, and I am not sure of the best way to do that. Specifically, I do NOT want to pass pointers because I would like a compile-time check on the dimensions, which (correct my if I am wrong) C gives me.

The most promising solution, which I see in a lot of places is to switch to a template approach. For example,

template<size_t a, size_t b>
void get_xu_col(int i_start,
                int n,
                double x[n],
                int n_x,
                int n_u,
                int n_col,
                double (&xu_col)[a][b]) {

However, this fails to compile with the puzzling error:

error: no matching function for call to 'get_xu_col'
    get_xu_col(id, n_vars, x, n_x, n_u, n_col, xu_col);
    ^~~~~~~~~~
note: candidate template ignored: could not match 'double' against 'double'

In both the C and C++ versions, I am calling this code like this:

int main(){
    ...
    double xu_col[n_col][n_x + n_u];
    get_xu_col( ..., xu_col );
    ...
}

Can somebody please tell me what that error message is trying to say? Or is there a better idiom for this?

I cannot use the standard library or Boost.

Claudio Cortese
  • 1,372
  • 2
  • 10
  • 21
bremen_matt
  • 6,902
  • 7
  • 42
  • 90
  • Judging by your [last question](https://stackoverflow.com/questions/48901482/c-passing-array-to-a-function-and-why-it-does-not-work-in-c), you seem to have overlooked the fact `x[n]` suffers from the same issue as the VLA parameter you tried to fix. – StoryTeller - Unslander Monica Feb 21 '18 at 09:28
  • Ahhh. That was dumb. Please post this as an answer and I will accept it. That error message did nothing for me... – bremen_matt Feb 21 '18 at 09:33
  • Nah, it's okay. If you can post a more detailed answer yourself, go on. [Self answers](https://stackoverflow.com/help/self-answer) are perfectly acceptable. – StoryTeller - Unslander Monica Feb 21 '18 at 09:34
  • Ok. But what is up with that error message? That is horrible. It gives no indication of the problem and seems to contradict itself (could not match 'double' against 'double') – bremen_matt Feb 21 '18 at 09:35
  • 1
    Well, that would be a case of the compiler failing harder while already failing. Your code wasn't valid C++ to begin with. Since templates are one complex beast of a feature, it's really hard to give decent error messages at times, even when everything else in the definition is correct. – StoryTeller - Unslander Monica Feb 21 '18 at 09:37

1 Answers1

1

As @StoryTeller points out, the issue is that I forgot a template parameter for the other array being passed. I should have written the template like

template<size_t a, size_t b, size_t c>
void get_xu_col(int i_start,
                int n,
                double (&x)[c],
                int n_x,
                int n_u,
                int n_col,
                double (&xu_col)[a][b]) {

obviously, we could improve this further by dropping some of the parameters being passed since they are identical to the template parameters...

bremen_matt
  • 6,902
  • 7
  • 42
  • 90
  • Curious to know why you can't use the standard library... if it's because you're compiling for some unusual hardware, how much storage is available? Reason being is that the template solution could massively increase the size of your binary depending on how many unique combinations of (a,b,c) you have. – virgesmith Feb 21 '18 at 10:37
  • That was misleading. No good reason for it. The reason I put that in the question is that I want to fundamentally understand how to solve the problem with the STL. If I excluded that requirement, then I am sure that I would have gotten 20 answers explaining that I should use std::vector or std::array. – bremen_matt Feb 21 '18 at 10:41
  • Fair enough, the best C++ solution by far is to use the STL though ;) – virgesmith Feb 21 '18 at 10:51
  • Actually, I need to pass some Eigen matrices. – bremen_matt Feb 21 '18 at 10:51
  • Ultimately, this function will get completely erased from the codebase since Eigen has the same functionality as this function. I was just trying to understand what the issue was. That error message was a really,really strange thing... – bremen_matt Feb 21 '18 at 10:53