我正在尝试通过将命令拆分为单独的文件来组织我的项目,以便于维护。我遇到的问题是尝试迭代编译时定义的命令数组。我创建了一个愚蠢的例子来重现我得到的错误。
.
├── CMakeLists.txt
├── commands
│ ├── CMakeLists.txt
│ ├── command.c
│ ├── command.h
│ ├── help_command.c
│ └── help_command.h
└── main.c
PROJECT(COMMAND_EXAMPLE)
SET(SRCS main.c)
ADD_SUBDIRECTORY(commands)
ADD_EXECUTABLE(test ${SRCS})
SET(SRCS ${SRCS} command.c help_command.c)
#ifndef COMMAND_H
#define COMMAND_H
struct command {
char* name;
int (*init)(int argc, char** argv);
int (*exec)(void);
};
extern struct command command_table[];
#endif
#include "command.h"
#include "help_command.h"
struct command command_table[] = {
{"help", help_init, help_exec},
};
#ifndef HELP_COMMAND_H
#define HELP_COMMAND_H
int help_command_init(int argc, char** argv);
int help_command_exec(void);
#endif
#include "help_command.h"
int help_command_init(int argc, char** argv)
{
return 0;
}
int help_command_exec(void)
{
return 0;
}
#include <stdio.h>
#include "commands/command.h"
int main(int argc, char** argv)
{
printf("num of commands: %d\n", sizeof(command_table) / sizeof(command_table[0]));
return 0;
}
如果你运行
mkdir build && cd build && cmake .. && make
发生以下错误
path/to/main.c:6:40: error: invalid application of 'sizeof' to incomplete type 'struct command[]'
那么,如果我甚至无法确定数组中的命令数量,如何迭代command_table
?
我意识到还有其他帖子出现同样的错误,但我花了一段时间试图弄清楚为什么这不起作用并继续失败:
答案 0 :(得分:14)
要让sizeof(command_table)
能够正常工作,需要看到:
static struct command command_table[] = {
{"help", help_init, help_exec},
};
但它只能看到这一点:
extern struct command command_table[];
看到sizeof()
永远无法弄清楚实际上有多少元素。
static
使数组在所有其他模块中不可见。您必须将其删除或解决它。
您的选项(删除static
后)是:
硬编码元素的数量,例如
extern struct command command_table[3];
定义一个额外的变量来保存元素的数量:
<强>命令/ COMMAND.C 强>
#include "command.h"
#include "help_command.h"
struct command command_table[] = {
{"help", help_init, help_exec},
};
size_t command_count = sizeof(command_table)/sizeof(command_table[0]);
<强>命令/ command.h 强>
...
extern struct command command_table[];
extern size_t command_count;
...
然后你只需使用command_count
。
答案 1 :(得分:1)
在commands/command.h
中明确数组元素的数量:
extern struct command command_table[3];