Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 654cb2f

Browse files
committedJul 26, 2022
Document possible work-arounds for shortcomings of inot-as-a-class.
1 parent da1f84f commit 654cb2f

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed
 

‎docs/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@ In the following documents you will find more information about the topics cover
3636
3. [Threadsafe `Serial`](threadsafe-serial.md)
3737
4. [Threadsafe `Wire`](threadsafe-wire.md)
3838
5. [Threadsafe `SPI`](threadsafe-spi.md)
39+
6. [FAQ Known Limitation](faq-compilation-failure.md)

‎docs/faq-compilation-failure.md

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
<img src="https://content.arduino.cc/website/Arduino_logo_teal.svg" height="100" align="right"/>
2+
3+
FAQ: Known issues of language constructs within `inot`-files and possible workarounds
4+
=====================================================================================
5+
Encapsulating the .inot file content within a class prohibits a wide range of typical C/C++ constructs. By encapsulating the .inot file within a namespace instead those issues can be prevented (see https://github.com/arduino-libraries/Arduino_Threads/pull/47). While this PR is not yet merged please refer to this document describing possible work-arounds.
6+
7+
### No forward declaration of functions
8+
```C++
9+
int myFunc(int const a, int const b);
10+
11+
void setup()
12+
{
13+
14+
}
15+
16+
void loop()
17+
{
18+
static int c = 0;
19+
c += myFunc(0,c);
20+
}
21+
22+
int myFunc(int const a, int const b)
23+
{
24+
return (a + b);
25+
}
26+
```
27+
This fails to compile because it doesn't look like a declaration and a definition but rather like an attempt to overload myFunc with the same signature (again) resulting in a compile error.
28+
29+
To fix this in the "class-wrapping" method, don't write forward declarations.
30+
```diff
31+
- int myFunc(int const a, int const b);
32+
```
33+
or declare them `static`. Note: This may have unintended side effects.
34+
```diff
35+
- int myFunc(int const a, int const b);
36+
+ static int myFunc(int const a, int const b);
37+
```
38+
39+
### Beware of the right function signature for callback functions
40+
```C++
41+
void myEventHandler()
42+
{
43+
/* Do something. */
44+
}
45+
46+
void setup()
47+
{
48+
attachInterrupt(digitalPinToInterrupt(2), myEventHandler, CHANGE);
49+
}
50+
51+
void loop()
52+
{
53+
54+
}
55+
```
56+
This fails to compile because myEventHandler has the function signature of `void Thread::myEventHandler(void)` and is a member function of `class Thread` while `attachInterrupt` expects a function with the signature `void myEventHandler(void)`.
57+
58+
To fix this in the "class-wrapping" method, add `static` in front of the callback declaration.
59+
```diff
60+
- void myEventHandler()
61+
+ static void myEventHandler()
62+
```
63+
64+
### No in-class-initialisation of a static member variables
65+
```C++
66+
static int my_global_variable = 0;
67+
68+
void setup()
69+
{
70+
71+
}
72+
73+
void loop()
74+
{
75+
76+
}
77+
```
78+
This fails to compile because in-class-initialisation of a static member variable is forbidden.
79+
80+
To fix this in the "class-wrapping" method, remove `static` or remove the initialization.
81+
```diff
82+
- static int my_global_variable = 0;
83+
+ int my_global_variable = 0;
84+
```
85+
or
86+
```diff
87+
- static int my_global_variable = 0;
88+
+ static int my_global_variable;
89+
90+
void setup()
91+
{
92+
my_global_variable = 0;
93+
}
94+
```
95+
96+
### Work-arounds for object instantiation in inot-files.
97+
```C++
98+
BusDevice lsm6dsox(Wire, LSM6DSOX_ADDRESS);
99+
100+
byte lsm6dsox_read_reg(byte reg_addr)
101+
{
102+
byte read_buf = 0;
103+
lsm6dsox.wire().write_then_read(&reg_addr, 1, &read_buf, 1);
104+
return read_buf;
105+
}
106+
```
107+
A possible work-around is
108+
```diff
109+
- BusDevice lsm6dsox(Wire, LSM6DSOX_ADDRESS);
110+
+ BusDevice lsm6dsox = BusDevice{Wire, LSM6DSOX_ADDRESS};
111+
```
112+
113+
### Functions need to be declared before calling them
114+
```C++
115+
void setup()
116+
{
117+
attachInterrupt(digitalPinToInterrupt(2), myEventHandler, CHANGE);
118+
}
119+
120+
void loop()
121+
{
122+
123+
}
124+
125+
static void myEventHandler()
126+
{
127+
/* Do something. */
128+
}
129+
```
130+
This fails to compile because `myEventHandler` is declared after `setup`/`loop` and currently there's not automatic prototype generation as done for the ino file (Note: Therefor it's a very easy trap to fall prey too).
131+
132+
A possible work-around is to move the declaration before the actual usage:
133+
```diff
134+
+ static void myEventHandler()
135+
+ {
136+
+ /* Do something. */
137+
+ }
138+
139+
140+
void setup()
141+
{
142+
attachInterrupt(digitalPinToInterrupt(2), myEventHandler, CHANGE);
143+
}
144+
145+
void loop()
146+
{
147+
148+
}
149+
150+
- static void myEventHandler()
151+
- {
152+
- /* Do something. */
153+
- }
154+
```

0 commit comments

Comments
 (0)
Please sign in to comment.