user80805: I have a very simple routine that lights up the built-in LED (pin 13) when a system tick timer fires off its interrupt.
I override the weak reference to int sysTickHook(void) found in hooks.c. I found that in generalfor this to work I need to use extern "C" linkage
The part that is bewildering is that this interrupt fires off fine without extern "C" if there are the comments above it as shown below. This is the minimal reproducible example I can find.  Can someone explain this?
I'm using the plain old Arduino IDE 1.8.16.
void setup() {
  pinMode(13,OUTPUT);  
  digitalWrite(13,LOW);
}

void loop() {}

// {          -- if you remove this line sysTickHook will not be called
// extern "C" -- if you remove this line sysTickHook will not be called
int sysTickHook()
{        
  digitalWrite(13,HIGH);
  return 0;
}


user4143: The problem is the preprocessor in the IDE. It's not clever enough to work out the extern "C" when adding function prototypes.
With your comments you end up with:
#include <Arduino.h>
#line 1 "/home/matt/t/t.ino"
#line 1 "/home/matt/t/t.ino"
void setup();
#line 6 "/home/matt/t/t.ino"
void loop();
#line 10 "/home/matt/t/t.ino"
 extern "C" int sysTickHook(); // << The extern gets added here from the comment
#line 1 "/home/matt/t/t.ino"
void setup() {
  pinMode(13,OUTPUT);  
  digitalWrite(13,LOW);
}

void loop() {}

// {          -- if you remove this line sysTickHook will not be called
// extern "C" -- if you remove this line sysTickHook will not be called
int sysTickHook()
{        
  digitalWrite(13,HIGH);
  return 0;
}

It finds the extern in the comment and thinks it's real code. If you remove the comment markers it ends up with broken code, as you have a stray { in there. If you remove the comments entirely you end up with the function in the C++ linkage, which changes the function name internally and doesn't then override the weak function. The same happens if you remove just the first comment.
Basically having those comments breaks the preprocessor in such a way that it works.  The proper way of doing it is:
void setup() {
  pinMode(13,OUTPUT);  
  digitalWrite(13,LOW);
}

void loop() {}

extern "C" {
  int sysTickHook()
  {        
    digitalWrite(13,HIGH);
    return 0;
  }
}


80805: <p>I have a very simple routine that lights up the built-in LED (pin 13) when a system tick timer fires off its interrupt.</p>
<p>I override the weak reference to <code>int sysTickHook(void)</code> found in <code>hooks.c</code>. I found that in generalfor this to work I need to use <code>extern &quot;C&quot;</code> linkage</p>
<p>The part that is bewildering is that this interrupt fires off fine <strong>without</strong> <code>extern &quot;C&quot;</code> <strong>if</strong> there are the comments above it as shown below. This is the minimal reproducible example I can find.  Can someone explain this?</p>
<p>I'm using the plain old Arduino IDE 1.8.16.</p>
<pre class="lang-c prettyprint-override"><code>void setup() {
  pinMode(13,OUTPUT);  
  digitalWrite(13,LOW);
}

void loop() {}

// {          -- if you remove this line sysTickHook will not be called
// extern &quot;C&quot; -- if you remove this line sysTickHook will not be called
int sysTickHook()
{        
  digitalWrite(13,HIGH);
  return 0;
}
</code></pre>
 4143: <p>The problem is the preprocessor in the IDE. It's not clever enough to work out the <code>extern &quot;C&quot;</code> when adding function prototypes.</p>
<p>With your comments you end up with:</p>
<pre class="lang-cpp prettyprint-override"><code>#include &lt;Arduino.h&gt;
#line 1 &quot;/home/matt/t/t.ino&quot;
#line 1 &quot;/home/matt/t/t.ino&quot;
void setup();
#line 6 &quot;/home/matt/t/t.ino&quot;
void loop();
#line 10 &quot;/home/matt/t/t.ino&quot;
 extern &quot;C&quot; int sysTickHook(); // &lt;&lt; The extern gets added here from the comment
#line 1 &quot;/home/matt/t/t.ino&quot;
void setup() {
  pinMode(13,OUTPUT);  
  digitalWrite(13,LOW);
}

void loop() {}

// {          -- if you remove this line sysTickHook will not be called
// extern &quot;C&quot; -- if you remove this line sysTickHook will not be called
int sysTickHook()
{        
  digitalWrite(13,HIGH);
  return 0;
}
</code></pre>
<p>It finds the <code>extern</code> in the comment and thinks it's real code. If you remove the comment markers it ends up with broken code, as you have a stray <code>{</code> in there. If you remove the comments entirely you end up with the function in the C++ linkage, which changes the function name internally and doesn't then override the weak function. The same happens if you remove just the first comment.</p>
<p>Basically having those comments breaks the preprocessor in such a way that it works.  The proper way of doing it is:</p>
<pre class="lang-cpp prettyprint-override"><code>void setup() {
  pinMode(13,OUTPUT);  
  digitalWrite(13,LOW);
}

void loop() {}

extern &quot;C&quot; {
  int sysTickHook()
  {        
    digitalWrite(13,HIGH);
    return 0;
  }
}
</code></pre>
