为什么从 shorthand 函数指针数组初始化调用函数不编译?
Why calling a function from shorthand function pointers array initialization doesn't compile?
我的项目中有以下代码:
printf("Please select one of the tests: ");
int n;
scanf("%d", &n);
(void (* [])()) {test1, test2, test3, test4}[n - 1]();
对我来说,这段代码可以按缩进方式编译和工作。但是我的教授说这不适合她。
我写的代码符合C23标准,我的编译器是Apple Clang v13.0.0。但是关于我的教授,我只知道她使用 MSVC 编译器;我没有关于她标记代码的编译器版本或标准的信息。
我尝试将 C 标准更改为 C99,但它仍然有效,所以我认为这一定是编译器问题。我没有 Windows 机器来玩 MSVC 并测试问题是否出在匿名数组初始化、紧随其后的下标运算符、整个事情之后的调用运算符,或者完全是其他问题。
现在,我当然知道我可以先声明一个函数指针数组,然后分配每个元素,或者为此目的只使用一个 switch
。我也知道这是一种“聪明的代码”,在更多人维护的实际项目中可能不受欢迎,但这是我的代码,仅为教育目的而创建。此外,我的教授喜欢这种“聪明的技巧”,作为你可以用这门语言做什么的极端例子。我想知道的是这段代码不能用 MSVC 编译的原因。该语法是某种特定于编译器的语言扩展,还是只是 Microsoft 一如既往地没有跟上对所有语言功能的支持?
您的老师可能正在将您的代码编译为 C++。
添加了虚拟函数后,如果将此代码放在 .c 文件中并使用 MSVC 2015 进行编译,则可以正常编译。如果文件的扩展名为 .cpp,则会生成以下错误:
x1.cpp(13): error C3260: ')': skipping unexpected token(s) before lambda body
x1.cpp(13): error C2143: syntax error: missing ';' before '}'
x1.cpp(13): warning C4550: expression evaluates to a function which is missing an argument list
x1.cpp(13): error C2676: binary '[': 'main::<lambda_8caaf9f5b122025ad6cda2ca258a66a7>' does not define this operator or a conversion to a type acceptable to the predefined operator
x1.cpp(13): error C2143: syntax error: missing ')' before ';'
x1.cpp(13): error C2059: syntax error: ';'
所以它认为你的复合文字是一个 lambda 函数。复合文字是一种 C-only 构造,因此除非您的 C++ 编译器支持它们作为扩展,否则它将无法工作。
让您的老师将您的代码编译为 C 语言,将其放入扩展名为 .c 的文件中。
或者,不要使用复合文字。先创建数组,再索引,调用函数
void (*f[])() = {test1, test2, test3, test4};
f[n - 1]();
我的项目中有以下代码:
printf("Please select one of the tests: ");
int n;
scanf("%d", &n);
(void (* [])()) {test1, test2, test3, test4}[n - 1]();
对我来说,这段代码可以按缩进方式编译和工作。但是我的教授说这不适合她。
我写的代码符合C23标准,我的编译器是Apple Clang v13.0.0。但是关于我的教授,我只知道她使用 MSVC 编译器;我没有关于她标记代码的编译器版本或标准的信息。
我尝试将 C 标准更改为 C99,但它仍然有效,所以我认为这一定是编译器问题。我没有 Windows 机器来玩 MSVC 并测试问题是否出在匿名数组初始化、紧随其后的下标运算符、整个事情之后的调用运算符,或者完全是其他问题。
现在,我当然知道我可以先声明一个函数指针数组,然后分配每个元素,或者为此目的只使用一个 switch
。我也知道这是一种“聪明的代码”,在更多人维护的实际项目中可能不受欢迎,但这是我的代码,仅为教育目的而创建。此外,我的教授喜欢这种“聪明的技巧”,作为你可以用这门语言做什么的极端例子。我想知道的是这段代码不能用 MSVC 编译的原因。该语法是某种特定于编译器的语言扩展,还是只是 Microsoft 一如既往地没有跟上对所有语言功能的支持?
您的老师可能正在将您的代码编译为 C++。
添加了虚拟函数后,如果将此代码放在 .c 文件中并使用 MSVC 2015 进行编译,则可以正常编译。如果文件的扩展名为 .cpp,则会生成以下错误:
x1.cpp(13): error C3260: ')': skipping unexpected token(s) before lambda body
x1.cpp(13): error C2143: syntax error: missing ';' before '}'
x1.cpp(13): warning C4550: expression evaluates to a function which is missing an argument list
x1.cpp(13): error C2676: binary '[': 'main::<lambda_8caaf9f5b122025ad6cda2ca258a66a7>' does not define this operator or a conversion to a type acceptable to the predefined operator
x1.cpp(13): error C2143: syntax error: missing ')' before ';'
x1.cpp(13): error C2059: syntax error: ';'
所以它认为你的复合文字是一个 lambda 函数。复合文字是一种 C-only 构造,因此除非您的 C++ 编译器支持它们作为扩展,否则它将无法工作。
让您的老师将您的代码编译为 C 语言,将其放入扩展名为 .c 的文件中。
或者,不要使用复合文字。先创建数组,再索引,调用函数
void (*f[])() = {test1, test2, test3, test4};
f[n - 1]();