opencode-skills-collection 3.0.49 → 3.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled-skills/.antigravity-install-manifest.json +27 -1
- package/bundled-skills/ab-test-setup/SKILL.md +14 -0
- package/bundled-skills/apple-notes-search/SKILL.md +122 -0
- package/bundled-skills/astropy/references/coordinates.md +9 -0
- package/bundled-skills/astropy/references/cosmology.md +8 -0
- package/bundled-skills/astropy/references/fits.md +8 -0
- package/bundled-skills/astropy/references/tables.md +8 -0
- package/bundled-skills/astropy/references/time.md +7 -0
- package/bundled-skills/astropy/references/units.md +9 -0
- package/bundled-skills/astropy/references/wcs_and_other_modules.md +9 -0
- package/bundled-skills/browser-extension-builder/SKILL.md +1 -1
- package/bundled-skills/ckw-design/SKILL.md +129 -0
- package/bundled-skills/deterministic-design/SKILL.md +56 -0
- package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
- package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
- package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
- package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
- package/bundled-skills/docs/users/bundles.md +1 -1
- package/bundled-skills/docs/users/claude-code-skills.md +1 -1
- package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
- package/bundled-skills/docs/users/getting-started.md +1 -1
- package/bundled-skills/docs/users/kiro-integration.md +1 -1
- package/bundled-skills/docs/users/usage.md +4 -4
- package/bundled-skills/docs/users/visual-guide.md +4 -4
- package/bundled-skills/lint-and-validate/SKILL.md +3 -1
- package/bundled-skills/lookdev/SKILL.md +229 -0
- package/bundled-skills/lookdev-auto/SKILL.md +102 -0
- package/bundled-skills/macos-screen-recorder/SKILL.md +59 -0
- package/bundled-skills/pr-merge-champion/SKILL.md +116 -0
- package/bundled-skills/programmatic-seo/SKILL.md +11 -0
- package/bundled-skills/schema-markup/SKILL.md +11 -0
- package/bundled-skills/screenstudio-alt/SKILL.md +91 -0
- package/bundled-skills/super-code/SKILL.md +209 -0
- package/bundled-skills/super-code/bash/SKILL.md +292 -0
- package/bundled-skills/super-code/c/SKILL.md +263 -0
- package/bundled-skills/super-code/cpp/SKILL.md +271 -0
- package/bundled-skills/super-code/csharp/SKILL.md +276 -0
- package/bundled-skills/super-code/dart/SKILL.md +327 -0
- package/bundled-skills/super-code/elixir/SKILL.md +366 -0
- package/bundled-skills/super-code/go/SKILL.md +234 -0
- package/bundled-skills/super-code/java/SKILL.md +230 -0
- package/bundled-skills/super-code/kotlin/SKILL.md +281 -0
- package/bundled-skills/super-code/php/SKILL.md +316 -0
- package/bundled-skills/super-code/python/SKILL.md +315 -0
- package/bundled-skills/super-code/ruby/SKILL.md +306 -0
- package/bundled-skills/super-code/rust/SKILL.md +289 -0
- package/bundled-skills/super-code/scala/SKILL.md +302 -0
- package/bundled-skills/super-code/swift/SKILL.md +299 -0
- package/bundled-skills/super-code/typescript/SKILL.md +286 -0
- package/bundled-skills/web-media-getter/SKILL.md +119 -0
- package/bundled-skills/youtube-seo-optimizer/SKILL.md +9 -9
- package/package.json +1 -1
- package/skills_index.json +574 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: c
|
|
3
|
+
description: "Language-specific super-code guidelines for c."
|
|
4
|
+
risk: safe
|
|
5
|
+
source: community
|
|
6
|
+
date_added: "2026-06-16"
|
|
7
|
+
---
|
|
8
|
+
# C: Idiomatic Efficiency Reference
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
1. [Memory Management](#memory)
|
|
12
|
+
2. [Pointers & Arrays](#pointers)
|
|
13
|
+
3. [Error Handling](#errors)
|
|
14
|
+
4. [Strings](#strings)
|
|
15
|
+
5. [Structs & Enums](#structs)
|
|
16
|
+
6. [Preprocessor & Headers](#preprocessor)
|
|
17
|
+
7. [Anti-patterns specific to C](#antipatterns)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1. Memory Management {#memory}
|
|
22
|
+
|
|
23
|
+
```c
|
|
24
|
+
// ❌ malloc without checking return value
|
|
25
|
+
char *buf = malloc(size);
|
|
26
|
+
strcpy(buf, src);
|
|
27
|
+
|
|
28
|
+
// ✅
|
|
29
|
+
char *buf = malloc(size);
|
|
30
|
+
if (!buf) return -ENOMEM;
|
|
31
|
+
memcpy(buf, src, size);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```c
|
|
35
|
+
// ❌ Casting malloc result (unnecessary in C, hides missing #include)
|
|
36
|
+
int *p = (int *)malloc(n * sizeof(int));
|
|
37
|
+
|
|
38
|
+
// ✅
|
|
39
|
+
int *p = malloc(n * sizeof *p);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```c
|
|
43
|
+
// ❌ free without nulling (dangling pointer risk in long-lived scope)
|
|
44
|
+
free(ptr);
|
|
45
|
+
// ... later code might use ptr
|
|
46
|
+
|
|
47
|
+
// ✅
|
|
48
|
+
free(ptr);
|
|
49
|
+
ptr = NULL;
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```c
|
|
53
|
+
// ❌ Forgetting to free on early-return paths
|
|
54
|
+
char *a = malloc(100);
|
|
55
|
+
char *b = malloc(200);
|
|
56
|
+
if (!b) return -1; // leaks a
|
|
57
|
+
|
|
58
|
+
// ✅ — single cleanup label
|
|
59
|
+
char *a = NULL, *b = NULL;
|
|
60
|
+
a = malloc(100);
|
|
61
|
+
if (!a) goto cleanup;
|
|
62
|
+
b = malloc(200);
|
|
63
|
+
if (!b) goto cleanup;
|
|
64
|
+
// ... use a, b ...
|
|
65
|
+
cleanup:
|
|
66
|
+
free(b);
|
|
67
|
+
free(a);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Use `sizeof *ptr` instead of `sizeof(Type)` — it stays correct when the type changes.**
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 2. Pointers & Arrays {#pointers}
|
|
75
|
+
|
|
76
|
+
```c
|
|
77
|
+
// ❌ Manual array size tracking
|
|
78
|
+
void process(int *arr, int len) { ... }
|
|
79
|
+
process(data, 10);
|
|
80
|
+
|
|
81
|
+
// ✅ — pass size alongside pointer, or use a struct
|
|
82
|
+
typedef struct { int *data; size_t len; } IntSlice;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```c
|
|
86
|
+
// ❌ Pointer arithmetic where array indexing is clearer
|
|
87
|
+
*(arr + i) = value;
|
|
88
|
+
|
|
89
|
+
// ✅
|
|
90
|
+
arr[i] = value;
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```c
|
|
94
|
+
// ❌ VLA in production code (stack overflow risk, optional in C11+)
|
|
95
|
+
int arr[n];
|
|
96
|
+
|
|
97
|
+
// ✅
|
|
98
|
+
int *arr = malloc(n * sizeof *arr);
|
|
99
|
+
if (!arr) return -ENOMEM;
|
|
100
|
+
// ... use arr ...
|
|
101
|
+
free(arr);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 3. Error Handling {#errors}
|
|
107
|
+
|
|
108
|
+
```c
|
|
109
|
+
// ❌ Using magic numbers for error returns
|
|
110
|
+
if (do_thing() == -1) { ... }
|
|
111
|
+
|
|
112
|
+
// ✅ — define or use named error codes
|
|
113
|
+
#include <errno.h>
|
|
114
|
+
if (do_thing() < 0) {
|
|
115
|
+
perror("do_thing");
|
|
116
|
+
return errno;
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
```c
|
|
121
|
+
// ❌ Deeply nested error checks
|
|
122
|
+
int r1 = step1();
|
|
123
|
+
if (r1 == 0) {
|
|
124
|
+
int r2 = step2();
|
|
125
|
+
if (r2 == 0) {
|
|
126
|
+
int r3 = step3();
|
|
127
|
+
// ...
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ✅ — early return / goto cleanup
|
|
132
|
+
if (step1() < 0) goto fail;
|
|
133
|
+
if (step2() < 0) goto fail;
|
|
134
|
+
if (step3() < 0) goto fail;
|
|
135
|
+
return 0;
|
|
136
|
+
fail:
|
|
137
|
+
cleanup();
|
|
138
|
+
return -1;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**`goto cleanup` is idiomatic C for resource teardown — don't avoid it out of principle.**
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 4. Strings {#strings}
|
|
146
|
+
|
|
147
|
+
```c
|
|
148
|
+
// ❌ strcpy without bounds checking
|
|
149
|
+
strcpy(dest, src);
|
|
150
|
+
|
|
151
|
+
// ✅
|
|
152
|
+
strncpy(dest, src, sizeof(dest) - 1);
|
|
153
|
+
dest[sizeof(dest) - 1] = '\0';
|
|
154
|
+
// or better: snprintf(dest, sizeof(dest), "%s", src);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
```c
|
|
158
|
+
// ❌ strcmp misuse
|
|
159
|
+
if (str == "hello") { ... } // compares pointers, not content
|
|
160
|
+
|
|
161
|
+
// ✅
|
|
162
|
+
if (strcmp(str, "hello") == 0) { ... }
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```c
|
|
166
|
+
// ❌ Building strings with repeated strcat (O(n²))
|
|
167
|
+
char result[1024] = "";
|
|
168
|
+
for (int i = 0; i < n; i++) {
|
|
169
|
+
strcat(result, items[i]);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// ✅ — track write position
|
|
173
|
+
char result[1024];
|
|
174
|
+
int pos = 0;
|
|
175
|
+
for (int i = 0; i < n && pos < (int)sizeof(result); i++) {
|
|
176
|
+
pos += snprintf(result + pos, sizeof(result) - pos, "%s", items[i]);
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Prefer `snprintf` over `sprintf` — always.**
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 5. Structs & Enums {#structs}
|
|
185
|
+
|
|
186
|
+
```c
|
|
187
|
+
// ❌ Bare struct requiring `struct` keyword everywhere
|
|
188
|
+
struct point { int x, y; };
|
|
189
|
+
struct point p = {1, 2};
|
|
190
|
+
|
|
191
|
+
// ✅
|
|
192
|
+
typedef struct { int x, y; } Point;
|
|
193
|
+
Point p = {1, 2};
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
```c
|
|
197
|
+
// ❌ Uninitialized struct
|
|
198
|
+
Point p;
|
|
199
|
+
use(p.x); // UB
|
|
200
|
+
|
|
201
|
+
// ✅
|
|
202
|
+
Point p = {0};
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```c
|
|
206
|
+
// ❌ Magic integer constants
|
|
207
|
+
if (state == 3) { ... }
|
|
208
|
+
|
|
209
|
+
// ✅
|
|
210
|
+
typedef enum { STATE_IDLE, STATE_RUNNING, STATE_DONE } State;
|
|
211
|
+
if (state == STATE_DONE) { ... }
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## 6. Preprocessor & Headers {#preprocessor}
|
|
217
|
+
|
|
218
|
+
```c
|
|
219
|
+
// ❌ Macro where inline function works (no type safety, double eval)
|
|
220
|
+
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
221
|
+
MAX(x++, y) // x incremented twice if x > y
|
|
222
|
+
|
|
223
|
+
// ✅
|
|
224
|
+
static inline int max_int(int a, int b) { return a > b ? a : b; }
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
```c
|
|
228
|
+
// ❌ No include guard
|
|
229
|
+
// my_header.h
|
|
230
|
+
struct Foo { int x; };
|
|
231
|
+
|
|
232
|
+
// ✅
|
|
233
|
+
#ifndef MY_HEADER_H
|
|
234
|
+
#define MY_HEADER_H
|
|
235
|
+
struct Foo { int x; };
|
|
236
|
+
#endif
|
|
237
|
+
// or: #pragma once (widely supported, not standard)
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Keep macros for conditional compilation and constants. Use `static inline` for logic.**
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 7. Anti-patterns specific to C {#antipatterns}
|
|
245
|
+
|
|
246
|
+
| Anti-pattern | Preferred |
|
|
247
|
+
|---|---|
|
|
248
|
+
| `sprintf` | `snprintf` with buffer size |
|
|
249
|
+
| `gets` | `fgets` (gets is removed in C11) |
|
|
250
|
+
| Casting `malloc` result | let implicit `void*` conversion work |
|
|
251
|
+
| `sizeof(Type)` in malloc | `sizeof *ptr` |
|
|
252
|
+
| VLA for large/runtime arrays | heap allocation |
|
|
253
|
+
| `void*` callbacks without context param | pass `void *ctx` alongside function pointer |
|
|
254
|
+
| Global mutable state | pass state through struct pointers |
|
|
255
|
+
| `assert` for runtime error handling | proper error return codes |
|
|
256
|
+
| Missing `const` on read-only pointer params | `const char *str` |
|
|
257
|
+
| Mixing signed/unsigned in comparisons | use consistent types, cast explicitly |
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
## Limitations
|
|
262
|
+
- These are language-specific guidelines and do not cover overall architectural decisions.
|
|
263
|
+
- Over-compression might reduce readability; apply judgement.
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cpp
|
|
3
|
+
description: "Language-specific super-code guidelines for cpp."
|
|
4
|
+
risk: safe
|
|
5
|
+
source: community
|
|
6
|
+
date_added: "2026-06-16"
|
|
7
|
+
---
|
|
8
|
+
# C++: Idiomatic Efficiency Reference
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
1. [Memory & Ownership](#memory)
|
|
12
|
+
2. [Modern Types & Containers](#types)
|
|
13
|
+
3. [Move Semantics & References](#move)
|
|
14
|
+
4. [Templates & Concepts](#templates)
|
|
15
|
+
5. [Error Handling](#errors)
|
|
16
|
+
6. [Concurrency](#concurrency)
|
|
17
|
+
7. [Anti-patterns specific to C++](#antipatterns)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1. Memory & Ownership {#memory}
|
|
22
|
+
|
|
23
|
+
```cpp
|
|
24
|
+
// ❌ Raw new/delete
|
|
25
|
+
Widget* w = new Widget();
|
|
26
|
+
// ... 15 lines later ...
|
|
27
|
+
delete w;
|
|
28
|
+
|
|
29
|
+
// ✅
|
|
30
|
+
auto w = std::make_unique<Widget>();
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```cpp
|
|
34
|
+
// ❌ Shared ownership when unique suffices
|
|
35
|
+
auto w = std::make_shared<Widget>();
|
|
36
|
+
transfer(w); // only one owner
|
|
37
|
+
|
|
38
|
+
// ✅ — unique_ptr; move when transferring
|
|
39
|
+
auto w = std::make_unique<Widget>();
|
|
40
|
+
transfer(std::move(w));
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```cpp
|
|
44
|
+
// ❌ new[] for dynamic arrays
|
|
45
|
+
int* arr = new int[n];
|
|
46
|
+
// ... use ...
|
|
47
|
+
delete[] arr;
|
|
48
|
+
|
|
49
|
+
// ✅
|
|
50
|
+
std::vector<int> arr(n);
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```cpp
|
|
54
|
+
// ❌ Manual RAII wrapper for file/mutex
|
|
55
|
+
FILE* f = fopen(path, "r");
|
|
56
|
+
// ... must remember fclose ...
|
|
57
|
+
|
|
58
|
+
// ✅
|
|
59
|
+
std::ifstream f(path);
|
|
60
|
+
// closes automatically at scope exit
|
|
61
|
+
// For non-standard resources: use unique_ptr with custom deleter
|
|
62
|
+
auto f = std::unique_ptr<FILE, decltype(&fclose)>(fopen(path, "r"), fclose);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Rule: if you type `new`, you almost certainly want `make_unique` or `make_shared`.**
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 2. Modern Types & Containers {#types}
|
|
70
|
+
|
|
71
|
+
```cpp
|
|
72
|
+
// ❌ C-style string manipulation
|
|
73
|
+
char buf[256];
|
|
74
|
+
sprintf(buf, "%s:%d", host, port);
|
|
75
|
+
|
|
76
|
+
// ✅
|
|
77
|
+
auto addr = std::format("{}:{}", host, port); // C++20
|
|
78
|
+
// or: auto addr = host + ":" + std::to_string(port);
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```cpp
|
|
82
|
+
// ❌ out-parameter for multiple returns
|
|
83
|
+
void compute(int input, int& result, std::string& error);
|
|
84
|
+
|
|
85
|
+
// ✅
|
|
86
|
+
struct ComputeResult { int value; std::string error; };
|
|
87
|
+
ComputeResult compute(int input);
|
|
88
|
+
// or: std::pair / std::tuple with structured bindings
|
|
89
|
+
auto [value, error] = compute(input);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
```cpp
|
|
93
|
+
// ❌ Manual loop to find element
|
|
94
|
+
int idx = -1;
|
|
95
|
+
for (int i = 0; i < vec.size(); i++) {
|
|
96
|
+
if (vec[i] == target) { idx = i; break; }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ✅
|
|
100
|
+
auto it = std::ranges::find(vec, target); // C++20
|
|
101
|
+
// or: std::find(vec.begin(), vec.end(), target);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```cpp
|
|
105
|
+
// ❌ Checking .find() != .end() then accessing
|
|
106
|
+
auto it = map.find(key);
|
|
107
|
+
if (it != map.end()) { use(it->second); }
|
|
108
|
+
|
|
109
|
+
// ✅ (C++20)
|
|
110
|
+
if (map.contains(key)) { use(map[key]); }
|
|
111
|
+
// or keep iterator version when you need the value without double lookup
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Use `std::string_view` for function parameters that don't need ownership.**
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 3. Move Semantics & References {#move}
|
|
119
|
+
|
|
120
|
+
```cpp
|
|
121
|
+
// ❌ Copying a large container into a function
|
|
122
|
+
void process(std::vector<Data> items) { ... } // copies on call
|
|
123
|
+
|
|
124
|
+
// ✅ — const ref for read, move for sink
|
|
125
|
+
void process(const std::vector<Data>& items) { ... } // read-only
|
|
126
|
+
void consume(std::vector<Data> items) { ... } // sink: caller moves in
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```cpp
|
|
130
|
+
// ❌ std::move on const object (silently copies)
|
|
131
|
+
const std::string s = "hello";
|
|
132
|
+
take(std::move(s)); // still copies
|
|
133
|
+
|
|
134
|
+
// ✅ — don't const things you intend to move
|
|
135
|
+
std::string s = "hello";
|
|
136
|
+
take(std::move(s));
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```cpp
|
|
140
|
+
// ❌ Returning std::move from local (prevents NRVO)
|
|
141
|
+
std::vector<int> build() {
|
|
142
|
+
std::vector<int> v;
|
|
143
|
+
// ... fill ...
|
|
144
|
+
return std::move(v); // pessimization
|
|
145
|
+
|
|
146
|
+
// ✅ — just return the local; compiler applies NRVO or implicit move
|
|
147
|
+
return v;
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 4. Templates & Concepts {#templates}
|
|
154
|
+
|
|
155
|
+
```cpp
|
|
156
|
+
// ❌ SFINAE soup
|
|
157
|
+
template<typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
|
158
|
+
T square(T x) { return x * x; }
|
|
159
|
+
|
|
160
|
+
// ✅ (C++20 concepts)
|
|
161
|
+
template<std::integral T>
|
|
162
|
+
T square(T x) { return x * x; }
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```cpp
|
|
166
|
+
// ❌ Template for one type
|
|
167
|
+
template<typename T>
|
|
168
|
+
void log(T msg) { std::cout << msg; }
|
|
169
|
+
// Only ever called with std::string
|
|
170
|
+
|
|
171
|
+
// ✅ — don't templatize unless you need multiple types
|
|
172
|
+
void log(std::string_view msg) { std::cout << msg; }
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
**Concepts make template errors readable — prefer them over SFINAE and static_assert.**
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 5. Error Handling {#errors}
|
|
180
|
+
|
|
181
|
+
```cpp
|
|
182
|
+
// ❌ Error codes via int returns (C-style in C++)
|
|
183
|
+
int parse(const std::string& input, Data& out);
|
|
184
|
+
|
|
185
|
+
// ✅ — std::expected (C++23) or exceptions
|
|
186
|
+
std::expected<Data, ParseError> parse(const std::string& input);
|
|
187
|
+
// or throw for exceptional conditions
|
|
188
|
+
Data parse(const std::string& input); // throws ParseError
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```cpp
|
|
192
|
+
// ❌ Catching by value (slices derived exceptions)
|
|
193
|
+
try { ... }
|
|
194
|
+
catch (std::exception e) { ... }
|
|
195
|
+
|
|
196
|
+
// ✅
|
|
197
|
+
catch (const std::exception& e) { ... }
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
```cpp
|
|
201
|
+
// ❌ Exception in destructor
|
|
202
|
+
~MyClass() {
|
|
203
|
+
if (cleanup() < 0) throw CleanupError(); // terminates
|
|
204
|
+
|
|
205
|
+
// ✅ — destructors must be noexcept; log/swallow errors
|
|
206
|
+
~MyClass() noexcept {
|
|
207
|
+
if (cleanup() < 0) log_error("cleanup failed");
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 6. Concurrency {#concurrency}
|
|
214
|
+
|
|
215
|
+
```cpp
|
|
216
|
+
// ❌ Manual thread + join tracking
|
|
217
|
+
std::thread t(work);
|
|
218
|
+
// ... must remember t.join() ...
|
|
219
|
+
|
|
220
|
+
// ✅ (C++20)
|
|
221
|
+
std::jthread t(work); // auto-joins on destruction
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
```cpp
|
|
225
|
+
// ❌ Lock/unlock manually
|
|
226
|
+
mtx.lock();
|
|
227
|
+
data.push_back(item);
|
|
228
|
+
mtx.unlock(); // missed on exception
|
|
229
|
+
|
|
230
|
+
// ✅
|
|
231
|
+
{
|
|
232
|
+
std::scoped_lock lock(mtx);
|
|
233
|
+
data.push_back(item);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
```cpp
|
|
238
|
+
// ❌ Polling a shared bool for completion
|
|
239
|
+
while (!done.load()) { std::this_thread::sleep_for(10ms); }
|
|
240
|
+
|
|
241
|
+
// ✅ — use std::future or condition_variable
|
|
242
|
+
auto future = std::async(std::launch::async, compute);
|
|
243
|
+
auto result = future.get();
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
**Use `std::scoped_lock` over `lock_guard` — it handles multiple mutexes and avoids deadlock.**
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 7. Anti-patterns specific to C++ {#antipatterns}
|
|
251
|
+
|
|
252
|
+
| Anti-pattern | Preferred |
|
|
253
|
+
|---|---|
|
|
254
|
+
| Raw `new`/`delete` | `make_unique` / `make_shared` |
|
|
255
|
+
| `(Type)expr` C-style cast | `static_cast<Type>(expr)` |
|
|
256
|
+
| `#define` constants | `constexpr` variables |
|
|
257
|
+
| `NULL` | `nullptr` |
|
|
258
|
+
| `using namespace std;` in headers | explicit `std::` prefix |
|
|
259
|
+
| Manual loop for transform/filter | `std::ranges` or `<algorithm>` |
|
|
260
|
+
| `std::endl` | `'\n'` (endl flushes — slow) |
|
|
261
|
+
| `char*` for string parameters | `std::string_view` |
|
|
262
|
+
| Exception specification `throw()` | `noexcept` |
|
|
263
|
+
| Inheriting from `std::` containers | composition, not inheritance |
|
|
264
|
+
| `volatile` for thread synchronization | `std::atomic` |
|
|
265
|
+
| Header-only mega-templates | separate declaration/definition where compile time matters |
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
## Limitations
|
|
270
|
+
- These are language-specific guidelines and do not cover overall architectural decisions.
|
|
271
|
+
- Over-compression might reduce readability; apply judgement.
|