Invalid storage class for a function in a macro in GCC

55,327

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.

Share:
55,327
feos
Author by

feos

Updated on October 03, 2020

Comments

  • feos
    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.