Error: ... was declared 'extern' and later 'static'

$ arduino-cli version
arduino-cli  Version: 1.2.2 Commit: c11b9dd5 Date: 2025-04-22T13:51:01Z

Compiling the next function:

static void set_default_item(beacon_list *item, const message *msg, const macadr_t mac)
{
  // code
}

Everything ok. But if I add linebreak for 80 columns rule:

static void
set_default_item(beacon_list *item, const message *msg, const macadr_t mac)
{
  // code
}

I got:

error: 'void set_default_item(beacon_list*, const message*, const uint8_t*)' was declared 'extern' and later 'static' [-fpermissive]

Sounds like a consequence of Arduino’s automatic prototype generation being a bit “off.”

What happens if you provide your own complete prototype?

this issue has been already faced here:

So, just don't add newlines there. :wink:

How to turn it off?

Hi @evily. The Arduino sketch build system always generates prototypes for functions in .ino files which don't have a manually defined prototype:

https://arduino.github.io/arduino-cli/latest/sketch-build-process/#pre-processing

There is no way to disable this.

However, this behavior is exclusive to the .ino files of the sketch. Code files with other extensions (e.g., .cpp, .c, .h) are compiled as-is. So if you don't want prototypes to be generated for your functions, you can create an additional .cpp file in the sketch folder and move the functions to that file. It will be compiled as pure C++.

It is mandatory for every Arduino sketch to contain a .ino file with name matching the sketch folder, but you are free to leave that file empty and instead implement the sketch in the .cpp file.

Just curiosity, but why you want that? What's the problem if you keep function definitions as single text lines?

Search for 80/24 rule.

I think this is a nicer way to reduce the line length:

static void set_default_item(
  beacon_list *item,
  const message *msg,
  const macadr_t mac)
{
  // code
}
1 Like

Agree, it's what I sometimes do.

Anyway, I checked this code (just changed parameter types with some standard ones) with my 2.3.5 IDE on Windows and compiled without any problem:

static void 
set_default_item(char *item, const char *msg, const int mac)
{
  // code
}

void setup() {
  set_default_item("item", "Message", 1);
}

void loop() {

}

I don't know if it's something related to the OS and/or the latest IDE/compiler...

It would be useful if @evily would provide a complete minimal demonstration sketch we can use to reproduce the fault.

The bug reported in Function prototype with newline compiler error? only occurs under specific conditions:

  • An .ino file contains a function definition with a line break after the type.
  • The function definition with a line break is the first definition.
  • The .ino file contains a manual function prototype.

From the information @evily provided, we know that the first of these conditions is present, but we don't know whether the other two exist.

Okay. I'll do it for you good sir.

I tried to compile the same code, got error:

$ arduino-cli compile -b esp32:esp32:esp32 forum.ino --warnings all
PATH/forum/forum.ino:2:1: error: 'void set_default_item(char*, const char*, int)' was declared 'extern' and later 'static' [-fpermissive]
    2 | set_default_item(char *item, const char *msg, const int mac)
      | ^~~~~~~~~~~~~~~~
PATH/forum/forum.ino: note: previous declaration of 'void set_default_item(char*, const char*, int)'
PATH/forum/forum.ino: In function 'void setup()':
PATH/forum/forum.ino:9:26: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
    9 |         set_default_item("a", "b", 1);
      |                          ^~~

Used platform Version Path
esp32:esp32   3.2.0   PATH
Error during build: exit status 1

Sorry, I can only say it looks like something related to your OS (Linux or Mac, still unknown...) and/or the version of your IDE and/or compiler (still unknown to me)...
I leave the floor to those who may know your environment better than me. Sorry.