问题描述
我正在尝试编译包含_Noreturn的代码:
I am trying to compile a piece of code that contains _Noreturn:
#ifndef SOMEHEADER_H
#define SOMEHEADER_H
#include <stdalign.h>
#include <stdbool.h>
#include <stdint.h>
extern struct s {
_Noreturn void (*somenoreturnfunc)(bool);
} svar;
#endif
哪个给我:
error: expected specifier-qualifier-list before '_Noreturn'
于:_Noreturn void (*somenoreturnfunc)(bool);
所以我尝试了:
#ifndef SOMEHEADER_H
#define SOMEHEADER_H
#include <stdalign.h>
#include <stdbool.h>
#include <stdint.h>
#include "noreturn.h"
extern struct s {
noreturn void (*somenoreturnfunc)(bool);
} svar;
#endif
noreturn.h:
noreturn.h:
#ifndef NO_RETURN_H
#define NO_RETURN_H
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define noreturn _Noreturn
#elif defined(__GNUC__)
#define noreturn __attribute__((noreturn))
#else
#define noreturn
#endif
#endif
但是错误仍然发生:
In file included from ../include/someinclude.h:8:0,
from src/main.c:17:
../include/noreturn.h:4:18: error: expected specifier-qualifier-list before '_Noreturn'
#define noreturn _Noreturn
^
../include/someinclude.h:19:5: note: in expansion of macro 'noreturn'
noreturn void (*somenoreturnfunc)(bool);
^
我很困惑,因为它是用c11编译的,因此应该可以工作:
I am baffled because it is compiled with c11 so it should work:
make V=1
cc src/main.c
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -std=c11 -Wall -pedantic -ffreestanding -static -I../libopencm3/include -I../include -DSTM32F1 -g -DDEBUG -DBUILD_STYLE=\"DEBUG\" -O0 -Iinclude -I../librt/include -MMD -MT build/main.o -MF build/main.d -o build/main.o -c src/main.c
In file included...
GCC版本为5.4.1:
GCC version is 5.4.1:
arm-none-eabi-gcc --version
arm-none-eabi-gcc (15:5.4.1+svn241155-1) 5.4.1 20160919
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
应该支持所有C11功能(从4.7开始,支持_Noreturn ).
which should support all C11 features (_Noreturn is supported since 4.7).
我在做什么错,我该如何解决该错误?
What am I doing wrong and how could I resolve this error?
-
也许一个独立的例子可以帮助您:
--
Maybe a self contained example can help:
main.c:
#include <stdalign.h>
#include <stdbool.h>
#include <stdint.h>
struct s {
_Noreturn void (*somenoreturnfunc)(bool);
} svar;
int main()
{
svar.somenoreturnfunc = 0;
return 0;
}
编译此:
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -std=c11 -Wall -pedantic -ffreestanding -static -DSTM32F1 -g -DDEBUG -DBUILD_STYLE=\"DEBUG\" -O0 -MMD -MT main.o -MF main.d -o main.o -c main.c
main.c:7:5: error: expected specifier-qualifier-list before '_Noreturn'
_Noreturn void (*somenoreturnfunc)(bool);
^
main.c:5:8: warning: struct has no members [-Wpedantic]
struct s {
^
main.c: In function 'main':
main.c:12:6: error: 'struct s' has no member named 'somenoreturnfunc'
svar.somenoreturnfunc = 0;
^
但是,使用相同的命令行进行编译并删除_Noreturn
时,编译成功.
Yet when compiling with the same command line and removing _Noreturn
the compilation succeeds.
使用编译时也会发生这种情况gcc -std=c11 -o main main.c
:
This also happens when compiling withgcc -std=c11 -o main main.c
:
$ gcc -std=c11 -o main main.c
main.c:7:5: error: expected specifier-qualifier-list before ‘_Noreturn’
_Noreturn void (*somenoreturnfunc)(bool);
^~~~~~~~~
main.c: In function ‘main’:
main.c:12:6: error: ‘struct s’ has no member named ‘somenoreturnfunc’
svar.somenoreturnfunc = 0;
^
$ gcc --version
gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
推荐答案
在ISO C中,不能在函数指针的声明中使用_Noreturn
.它只能在函数声明中使用. (参考:C11 6.7.4/2).
In ISO C, _Noreturn
cannot be used on the declaration of a function pointer. It can only be used on the declaration of a function. (Ref: C11 6.7.4/2).
您将不得不放弃这个想法.函数说明符(inline
和_Noreturn
)不是函数类型的一部分.
You will have to abandon this idea. The function specifiers (inline
and _Noreturn
) are not part of a function's type.
您的代码中还有另一个问题:您在标头中定义svar
,如果标头包含在两个或多个翻译单元中,则会导致违反ODR.它应该只在标头中有一个声明,并在一个单元中有一个定义.
There is another problem in your code: you define svar
in the header, this will cause an ODR violation if the header is included in two or more translation units. It should only have a declaration in the header, and a definition in one unit.
要通过函数指针进行调用并保留_Noreturn
语义,也许您可以制作垫片,例如:
To call through the function pointer and retain _Noreturn
semantics , perhaps you could make a shim, e.g.:
inline _Noreturn void call_somefunc( struct s *ps, bool b )
{
ps->somenoreturnfunc(b);
}
但是没有办法让编译器强制执行,当您分配给函数指针时,它实际上是一个_Noreturn
函数.
but there is no way to have the compiler enforce that when you assign to the function pointer, it is actually a _Noreturn
function.
这篇关于_Noreturn in c中的结构:错误:'_Noreturn'之前的预期specifier-qualifier-list的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!