0

While reviewing C code that has been migrated from AIX to Cygwin 64-bit, I came across the following snippet. Writing only "static" within the "#ifndef" directive doesn't make sense to me. Since no documentation or help was available, I am asking for help here to understand the meaning of this code. Could someone explain if the code is valid and, if so, why? It appears to compile and run, but what effect will "static" have here?

#ifndef __CYGWIN__
#define __CYGWIN__

static const char ccm_version[] = "%%%CCM_VERSION: %full_filespec: %%%"; /*#006#*/

#ifdef __CYGWIN__
static
#endif
void somefunc(void);
void somefunc(void) { 
    printf("%s \n", ccm_version); 
} /*#006#*/

I am using Cygwin 64 bit on Windows 11 Pro and gcc (GCC) 11.3.0

aashoo
  • 404
  • 4
  • 13
  • If symbol __CYGWIN__ is defined, the function declaration will be `static void somefunc(void);` which makes the function static. – Lorinczy Zsigmond Jun 17 '23 at 15:14
  • @LorinczyZsigmond Thanks for the reply. Is there any way I can verify this (eg.using gdb or other tool). Asking this because as per your reply, if symbol CYGWIN is defined, then function declaration will include static in it. But how will it affect the behavior ? Because definition will be same regardless of symbol CYGWIN defined or not. Also if there are more variables/structs/functions along-with static inside #ifndef will function declaration be converted in same way ? – aashoo Jun 18 '23 at 09:55
  • In this context, `static` means _this function/variable is not available from other compilation units._ You can examine the generated object module with `nm -g`: static functions/variables aren't listed. (Declaration(s) and definition should be the same; in this case the declaration could be dropped, and definition should be `static`) – Lorinczy Zsigmond Jun 18 '23 at 10:28

1 Answers1

0

It is valid and in case __CYGWIN__ is defined, the code applies static to the function prototype: static void somefunc(void);. So it's equivalent to this:

#ifdef __CYGWIN__
  static void somefunc(void);
#else
  void somefunc(void);
#endif

Having a function declaration immediately followed by the corresponding function definition is rather pointless... they could as well have applied the static storage specifier directly to the function definition.

As for what that's supposed to be good for here, I can't say for sure without some context. Making a function static will give it internal linkage and limit access from other translation units. Reasons for doing so could be private encapsulation, resolving multiple identifier linker problems, doing some local unit testing, encouraging function inlining etc etc. Why it was used here, I can't tell, though encouraging inlining during code generation seems likely.

Lundin
  • 195,001
  • 40
  • 254
  • 396