Thank you Marco, If you removed that and things still works as expected when +1 here.. just please try to cover as much runtime configurations as possible during build/runtime verification :-)
Probably that was an outcome of working with some older picky compiler.. and hopefully not valid problem anymore.. can anyone recall? If no objections we can clean up stuff, with option A to be well aligned with existing "extern" standards :-) -- CeDeROM, SQ7MHZ, http://www.tomek.cedro.info On Tue, Oct 27, 2026 at 11:41 AM Marco C. <[email protected]> wrote: > > Hello, > > I would like to propose a change to the coding standard for global data > declarations in header files. > > Today Documentation/contributing/coding_style.rst asks every header to > define EXTERN at the start of its "Public Data" section: > > #ifdef __cplusplus > #define EXTERN extern "C" > extern "C" > { > #else > #define EXTERN extern > #endif > > and to "#undef EXTERN" at its end. Global data is then declared with > "EXTERN int g_foo;". > > Some numbers from include/ on master: > > - 540 headers define EXTERN. > - Only 20 of them use it, for about 50 declarations. > - The other 520 define and undefine it and never use it. > > Until 2013 the headers also declared their functions with EXTERN; the > 2014 coding standard then said that functions do not use it. The > definition stayed in the template, so most headers still define a macro > that nothing in them uses. > > There are two problems with the macro: > > 1. In our headers it adds nothing. All the declarations with EXTERN are > inside the extern "C" block of the same header (I checked the 20 > headers), so for C++ "extern int g_foo;" has C linkage too, and plain > "extern" gives the same result in C and C++. EXTERN is defined only as > extern or extern "C", and no file uses it for another purpose. Its one > use is as a safety net: a declaration put outside the extern "C" block > by mistake would still get C linkage. > > 2. EXTERN is not a reserved name. A program can define its own EXTERN, > and every system header that it includes after that removes the > program's definition with "#undef EXTERN". For example, Tcl's tcl.h > defines EXTERN, then tclInt.h includes system headers, and Tcl's own > "EXTERN void TclAllocateFreeObjects(void);" no longer compiles. > > I propose two steps. > > 1. Remove the unused definitions from the 520 headers that never use > EXTERN: the "#undef EXTERN", the two "#define EXTERN" lines and the > "#else" that holds one of them. The extern "C" block for C++ stays, > so the code that the compiler sees does not change. I have this > change ready (517 headers; three are left out because their SPDX > copyright lines do not pass nxstyle) and can send it as a PR. > > 2. Change the rule for the 20 headers that declare data and for new code. > These include common headers: unistd.h (optarg, ...), time.h (tzname), > netdb.h (h_errno), netinet/in.h (in6addr_any, ...). Two options: > > A. Plain "extern" inside the extern "C" block, as glibc, musl and the > BSD headers do. The coding standard drops the EXTERN definition > from the template. > > B. Keep the macro, under a reserved name: __EXTERN. Names that start > with two underscores belong to the implementation, so no program > can use them. The template keeps its form. > > Both work with every compiler that NuttX supports (GCC, clang, SDCC, > ZDS-II, IAR, Green Hills, TASKING, MSVC): they are plain C and do not > need #pragma push_macro. A is simpler; B is a smaller change of habits. > In both cases I can make the change of the 20 headers and of > coding_style.rst. > > Is step 1 welcome as a PR, and which option do you prefer for step 2? > > Regards, > Marco Casaroli
