I am writing a small C code for an algorithm. The main target are embedded microcontrollers, however, for testing purposes, a Matlab/Python interface is required.
我正在为一个算法编写一个小的C代码。主要目标是嵌入式微控制器,但是为了测试目的,需要一个Matlab/Python接口。
I am following an embedded programming standard (MISRA-C 2004), which requires the use of C90, and discourage the use of malloc
and friends. Therefore, all the arrays in the code have their memory allocated at compile time. If you change the size of the input arrays, you need to recompile the code, which is alright in the microcontroller scenario. However, when prototyping with Matlab/Python, the size of the input arrays change rather often, and recompiling every time does not seem like an option. In this case, the use of C99 is acceptable, and the size of the arrays should be determined in runtime.
我正在遵循一个嵌入式编程标准(MISRA-C 2004),它要求使用C90,并且不鼓励使用malloc和friends。因此,代码中的所有数组都在编译时分配它们的内存。如果更改了输入数组的大小,则需要重新编译代码,这在microcontroller场景中没有问题。然而,当使用Matlab/Python进行原型设计时,输入数组的大小经常会发生变化,而且每次重新编译都不像是一个选项。在这种情况下,C99的使用是可以接受的,并且数组的大小应该在运行时确定。
The question is: what options do I have in C to make these two scenarios coexist in the same code, while keeping the code clean?
问题是:我在C中有什么选项可以使这两个场景同时存在于同一代码中,同时保持代码的整洁?
I must emphasize that my main concern is how to make the code easy to maintain. I have considered using #ifdef to either take the statically allocated array or the dynamically alocated array. But there are too many arrays, I think #ifdef makes the code look ugly.
我必须强调,我主要关心的是如何使代码易于维护。我考虑过使用#ifdef获取静态分配的数组或动态分配的数组。但是数组太多了,我认为#ifdef使代码看起来很难看。
2 个解决方案
#1
3
I've thought of a way that you can get away with only one #ifdef
. I would personally just bite the bullet and recompile my code when I need to. The idea of using a different dialect of C for production and test makes me a bit nervous.
我想到了一种方法,你只需要一个#ifdef就能逃过一劫。我个人只会咬紧牙关,在需要的时候重新编译代码。使用不同的C语言进行生产和测试的想法让我有点紧张。
Anyway, here's what you can do.
不管怎样,这是你能做的。
#ifdef EMBEDDED
#define ARRAY_SIZE(V,S) (S)
#else
#define ARRAY_SIZE(V,S) (V)
#endif
int myFunc(int n)
{
int myArray[ARRAY_SIZE(n, 6)];
// work with myArray
}
The ARRAY_SIZE
macro chooses the variable V
, if not in the embedded environment; or the fixed size S
, if in the embedded environment.
ARRAY_SIZE宏选择变量V,如果不在嵌入式环境中;或者固定大小的S,如果在嵌入式环境中。
#2
1
MISRA-C:2004 forbids C99 and thereby VLAs, so if you are writing strictly-conforming MISRA code you can't use them. It is also very likely that VLAs will be explicitly banned in the upcoming MISRA-C standard.
MISRA- c:2004禁止C99,因此VLAs,所以如果您正在编写严格遵循MISRA代码,则不能使用它们。在即将发布的MISRA-C标准中,VLAs也很可能被明确禁止。
Is it an option not to use statically allocated arrays of unknown size? That is:
是否可以选择不使用静态分配的未知大小数组?那就是:
uint8_t arr[] = { ... };
...
n = sizeof(arr)/sizeof(uint8_t);
This is most likely the "prettiest" way. Alternatively you can have a debug build in C99 with VLAs, and then change it to statically allocated arrays in the release build.
这很可能是“最漂亮”的方式。或者,您可以在C99中使用VLAs进行调试,然后将其更改为在发布版本中静态分配的数组。
#1
3
I've thought of a way that you can get away with only one #ifdef
. I would personally just bite the bullet and recompile my code when I need to. The idea of using a different dialect of C for production and test makes me a bit nervous.
我想到了一种方法,你只需要一个#ifdef就能逃过一劫。我个人只会咬紧牙关,在需要的时候重新编译代码。使用不同的C语言进行生产和测试的想法让我有点紧张。
Anyway, here's what you can do.
不管怎样,这是你能做的。
#ifdef EMBEDDED
#define ARRAY_SIZE(V,S) (S)
#else
#define ARRAY_SIZE(V,S) (V)
#endif
int myFunc(int n)
{
int myArray[ARRAY_SIZE(n, 6)];
// work with myArray
}
The ARRAY_SIZE
macro chooses the variable V
, if not in the embedded environment; or the fixed size S
, if in the embedded environment.
ARRAY_SIZE宏选择变量V,如果不在嵌入式环境中;或者固定大小的S,如果在嵌入式环境中。
#2
1
MISRA-C:2004 forbids C99 and thereby VLAs, so if you are writing strictly-conforming MISRA code you can't use them. It is also very likely that VLAs will be explicitly banned in the upcoming MISRA-C standard.
MISRA- c:2004禁止C99,因此VLAs,所以如果您正在编写严格遵循MISRA代码,则不能使用它们。在即将发布的MISRA-C标准中,VLAs也很可能被明确禁止。
Is it an option not to use statically allocated arrays of unknown size? That is:
是否可以选择不使用静态分配的未知大小数组?那就是:
uint8_t arr[] = { ... };
...
n = sizeof(arr)/sizeof(uint8_t);
This is most likely the "prettiest" way. Alternatively you can have a debug build in C99 with VLAs, and then change it to statically allocated arrays in the release build.
这很可能是“最漂亮”的方式。或者,您可以在C99中使用VLAs进行调试,然后将其更改为在发布版本中静态分配的数组。