-2

In a C header file included in a C++ project, I have functions that take in arrays of passed-in sizes. The function prototypes show errors when compiling in a C++ environment, but they compiled without issues in the past. Here is the the header file and the corresponding C file. I am compiling with GCC. All of the arrays that are passed into the functions are known sizes and are allocated on the stack. What could be causing these errors?

Sample of Matrix.h:

#ifndef MATRIX_H
#define MATRIX_H

#ifdef __cplusplus
extern "C" {
#endif

#include "stdint.h"
#include "stdbool.h"

void matrixAdd(uint32_t r, uint32_t c, 
               float mat1[r][c], const float mat2[r][c]);

void matrixMultiply(uint32_t r1, uint32_t c1, uint32_t r2, uint32_t c2, 
                    const float mat1[r1][c1], const float mat2[r2][c2], 
                    float mat0[r1][c2]);

void matrixTranspose(uint32_t r1, uint32_t c1, const float mat1[r1][c1], 
                     float matT[c1][r1]);

bool matrixInverse(uint32_t s, const float mat1[s][s], float matI[s][s]);

void matrixCoefMultiply(uint32_t r, uint32_t c, float mat1[r][c], float);

#ifdef __cplusplus
}
#endif

#endif

Gives the errors:

In file included from src/GNC.h:10,
                 from src/main.cpp:10:
src/Matrix.h:38:28: error: use of parameter outside function body before ']' token
   38 |                float mat1[r][c], const float mat2[r][c]);
      |                            ^
src/Matrix.h:38:31: error: use of parameter outside function body before ']' token
   38 |                float mat1[r][c], const float mat2[r][c]);
      |                               ^
src/Matrix.h:38:32: error: expected ')' before ',' token
   38 |                float mat1[r][c], const float mat2[r][c]);
      |                                ^
      |                                )
src/Matrix.h:37:15: note: to match this '('
   37 | void matrixAdd(uint32_t r, uint32_t c,
      |               ^
src/Matrix.h:38:34: error: expected unqualified-id before 'const'
   38 |                float mat1[r][c], const float mat2[r][c]);
      |                                  ^~~~~
src/Matrix.h:41:40: error: use of parameter outside function body before ']' token
   41 |                     const float mat1[r1][c1], const float mat2[r2][c2],
      |                                        ^
src/Matrix.h:41:44: error: use of parameter outside function body before ']' token
   41 |                     const float mat1[r1][c1], const float mat2[r2][c2],
      |                                            ^
src/Matrix.h:41:45: error: expected ')' before ',' token
   41 |                     const float mat1[r1][c1], const float mat2[r2][c2],
      |                                             ^
      |                                             )
src/Matrix.h:40:20: note: to match this '('
   40 | void matrixMultiply(uint32_t r1, uint32_t c1, uint32_t r2, uint32_t c2,
      |                    ^
src/Matrix.h:41:47: error: expected unqualified-id before 'const'
   41 |                     const float mat1[r1][c1], const float mat2[r2][c2],
      |                                               ^~~~~
src/Matrix.h:44:67: error: use of parameter outside function body before ']' token
   44 | void matrixTranspose(uint32_t r1, uint32_t c1, const float mat1[r1][c1],
      |                                                                   ^
src/Matrix.h:44:71: error: use of parameter outside function body before ']' token
   44 | void matrixTranspose(uint32_t r1, uint32_t c1, const float mat1[r1][c1],
      |                                                                       ^
src/Matrix.h:44:72: error: expected ')' before ',' token
   44 | void matrixTranspose(uint32_t r1, uint32_t c1, const float mat1[r1][c1],
      |                     ~                                                  ^
      |                                                                        )
src/Matrix.h:45:22: error: expected unqualified-id before 'float'
   45 |                      float matT[c1][r1]);
      |                      ^~~~~
src/Matrix.h:47:50: error: use of parameter outside function body before ']' token
   47 | bool matrixInverse(uint32_t s, const float mat1[s][s], float matI[s][s]);
      |                                                  ^
src/Matrix.h:47:53: error: use of parameter outside function body before ']' token
   47 | bool matrixInverse(uint32_t s, const float mat1[s][s], float matI[s][s]);
      |                                                     ^
src/Matrix.h:47:54: error: expected ')' before ',' token
   47 | bool matrixInverse(uint32_t s, const float mat1[s][s], float matI[s][s]);
      |                   ~                                  ^
      |                                                      )
src/Matrix.h:47:56: error: expected unqualified-id before 'float'
   47 | bool matrixInverse(uint32_t s, const float mat1[s][s], float matI[s][s]);
      |                                                        ^~~~~
src/Matrix.h:49:61: error: use of parameter outside function body before ']' token
   49 | void matrixCoefMultiply(uint32_t r, uint32_t c, float mat1[r][c], float);
      |                                                             ^
src/Matrix.h:49:64: error: use of parameter outside function body before ']' token
   49 | void matrixCoefMultiply(uint32_t r, uint32_t c, float mat1[r][c], float);
      |                                                                ^
src/Matrix.h:49:65: error: expected ')' before ',' token
Compiling .pio/build/adafruit_itsybitsy_m4/lib47f/Adafruit_TinyUSB_Arduino/class/cdc/cdc_device.c.o
   49 | void matrixCoefMultiply(uint32_t r, uint32_t c, float mat1[r][c], float);
      |                        ~                                        ^
      |                                                                 )
src/Matrix.h:49:67: error: expected unqualified-id before 'float'
   49 | void matrixCoefMultiply(uint32_t r, uint32_t c, float mat1[r][c], float);
      |                                                                   ^~~~~
*** [.pio/build/adafruit_itsybitsy_m4/src/main.cpp.o] Error 1

The functions are used like the following:

void foo(void)
{
    float A[2][2] = {
        {1, 0},
        {0, 1}
    };
    float B[2][2] = {
        {1, 1},
        {0, 1}
    };
    matrixAdd(2, 2, A, B);

    /* Do other stuff */
}
  • 1
    https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard?r=Saves_AllUserSaves – πάντα ῥεῖ Jun 17 '23 at 10:20
  • Compiler error messages usually have some context. Do not edit it out. Post the entire output. – n. m. could be an AI Jun 17 '23 at 10:28
  • Please post compiler version, used compiler options and the exact verbatim full all messages from the compiler. – KamilCuk Jun 17 '23 at 10:49
  • gcc version: 12.2.1 20230201 arm-none-eabi-gcc Compiler options: "-mfloat-abi=hard", "-mfpu=fpv4-sp-d16", "-mcpu=cortex-m4", "-mthumb", – TheRedstoneHive Jun 17 '23 at 11:14
  • Is this a [mcve] of your problem: https://godbolt.org/z/jfP3jxK6v It's valid C code: https://wandbox.org/permlink/OhC8dLsyRPeLt7CQ But it's not valid C++ code: https://wandbox.org/permlink/Ky5TVuWpObJi0udb C is not a subset of C++. If you want to write code for C and C++, it has to be valid C and C++ code. – jabaa Jun 17 '23 at 11:51
  • Honestly I'm not sure how to provide a minimal reproducible example without sending the entire project. The code provided above worked just fine a few days ago, so I'm guessing I have messed up somewhere else in some config. I'm kinda just hoping someone else has encountered the same problem in the past and sees this post lol. – TheRedstoneHive Jun 17 '23 at 12:09
  • The problem is answered by the link in the first comment by @πάνταῥεῖ. You're using code which isn't valid C++. – Some programmer dude Jun 17 '23 at 14:13
  • But it's being compiled as C, no? It compiled just fine in the past. – TheRedstoneHive Jun 17 '23 at 21:59
  • How do you compile the code? The filenames are `*.cpp`. `gcc` compiles these files as C++ code. – jabaa Jun 17 '23 at 22:01
  • Matrix.h is only ever included by a c header (GNC.c), but GNC.h is included by a cpp file. That's why I have the extern C guards. – TheRedstoneHive Jun 17 '23 at 22:18
  • cpp files are compiled as C++ code and your code isn't valid C++ code. The errors come from `.pio/build/adafruit_itsybitsy_m4/src/main.cpp.o` Looks like a cpp file. – jabaa Jun 17 '23 at 22:20
  • How can I ensure it is compiled as a c file? main.cpp includes GNC.h (c) which includes Matrix.h (c). – TheRedstoneHive Jun 17 '23 at 22:25
  • You could call the file `main.c`. Why would you call the file `main.cpp` if it's C code? Why would you use `#ifdef __cplusplus` if the code can't be compiled as C++ code? – jabaa Jun 17 '23 at 22:28
  • Because main.cpp is a cpp file, it contains cpp only code. GNC.c and Matrix.c are C only and so I called them .c so that they could be compiled as C files, but the error seems to be in the header which is included in a .cpp file, so I put C guards. – TheRedstoneHive Jun 17 '23 at 22:33
  • A C++ file can't include C code that is invalid C++ code. A translation unit consists of the source file and all header files. A translation unit is either compiled as C code or as C++ code and it has to contain valid C code or valid C++ code. It can't be a mix of C and C++ code that is neither valid C code nor valid C++ code. One way could be to compile the C code as a library and link it with your C++ code. But the API has to be valid C++ code. – jabaa Jun 17 '23 at 22:34
  • does extern "C" {/*valid C code */} not work to prevent that issue? – TheRedstoneHive Jun 17 '23 at 22:38
  • No, it only handles the differences in name mangling. – jabaa Jun 17 '23 at 22:41
  • Thank you for clarifying, it's fixed now. – TheRedstoneHive Jun 17 '23 at 23:05

1 Answers1

0

The issue was including a C header with C only features in a header file which was included in a cpp file. To fix, I moved the include of Matrix.h to the respective C file of the header it was included to, which meant it was only compiled as C.