Invalid storage class for a function in a macro in GCC
Solution 1
You can't declare a static function inside of another one. You need to put the declaration outside of void(x)
:
#define ASYNC_FUNCTION(x) \
static void internal ## x (ASYNCIOCB *); \
void x(void) { \
ASYNCIOCB *aiocb = AcquireAsyncIOCB(); \
CallAsyncNativeFunction_md(aiocb, internal ## x); \
} \
static void internal ## x (ASYNCIOCB *aiocb)
Then, if you run the source through just the preprocessor via gcc -E
, you'll get something like this (extra spacing added):
static void internalOccasional_function_name (ASYNCIOCB *);
void Occasional_function_name(void)
{
ASYNCIOCB *aiocb = AcquireAsyncIOCB();
CallAsyncNativeFunction_md(aiocb, internalOccasional_function_name);
}
static void internalOccasional_function_name (ASYNCIOCB *aiocb)
{
{
int a=1;
}
ASYNC_resumeThread();
}
Solution 2
In C language local function declarations can optionally include storage class specifier extern
. That's the only storage class specifier a local function declaration may have. No other storage class specifiers are allowed.
6.7.1/7:
The declaration of an identifier for a function that has block scope shall have no explicit storage-class specifier other than extern.
feos
Updated on October 03, 2020Comments
-
feos over 3 years
I have this legacy macro
#define ASYNC_FUNCTION(x) \ void x(void) { \ static void internal ## x (ASYNCIOCB *); \ ASYNCIOCB *aiocb = AcquireAsyncIOCB(); \ CallAsyncNativeFunction_md(aiocb, internal ## x); \ } \ static void internal ## x (ASYNCIOCB *aiocb)
followed by this one
#define ASYNC_FUNCTION_START(x) ASYNC_FUNCTION(x) { #define ASYNC_FUNCTION_END ASYNC_resumeThread(); }
And their use looks like this:
ASYNC_FUNCTION_START(Occasional_function_name) { //actual stuff } ASYNC_FUNCTION_END
It compiles fine with cl, but gcc gives
invalid storage class for function ‘internalOccasional_function_name’ static void internal##x (ASYNCIOCB *); ^
I tried to expand them all just to see what it becomes and found nothing broken. I also searched for unclosed curved brackets in the file, and found other macros like this
#define Foo_Bar1() { \ extern int foo; \ int bar = foo; \ if (condition) { \ Bar_Foo(); \ } \ #define Foo_Bar2() \ if (condibar != footion1){ \ AbortAsyncIOCB(aiocb); \ return; \ } \ if (condition) { \ Bar_Foo(); \ } \ }
No other headers are included, so other than that last macro looking weird, I couldn't find any obvious errors. I'm using cygwin and I'm fairly clueless.