Skip to content

Commit c1eeda6

Browse files
Feat/godbolt integration (#24)
* add interative codes * tidy todos * feat: enable to modify the compile condition
1 parent 7676bfc commit c1eeda6

178 files changed

Lines changed: 5024 additions & 6056 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Compiler Explorer examples
2+
3+
This directory contains small, single-file snippets used by the VitePress
4+
`OnlineCompilerDemo` component.
5+
6+
These files should be committed with the documentation changes that reference
7+
them. The component reads `arm-source-path` from the published repository, and
8+
keeps a small built-in fallback only so local previews keep working before the
9+
new files reach the default branch.
10+
11+
Guidelines:
12+
13+
- Keep each file self-contained.
14+
- Prefer freestanding-friendly headers such as `<cstdint>` and `<cstddef>`.
15+
- Avoid `iostream`, hosted-only containers, exceptions, dynamic allocation, and
16+
board-specific HAL headers in ARM snippets.
17+
- Use these snippets for assembly inspection, not as full tutorial programs.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// array_vs_carray_arm.cpp
2+
// ARM freestanding: std::array 与 C 数组的零开销对比
3+
4+
#include <cstddef>
5+
#include <cstdint>
6+
7+
int sum_raw(const int* data, std::size_t n) {
8+
int total = 0;
9+
for (std::size_t i = 0; i < n; ++i) {
10+
total += data[i];
11+
}
12+
return total;
13+
}
14+
15+
template <std::size_t N> int sum_array(const int (&data)[N]) {
16+
int total = 0;
17+
for (std::size_t i = 0; i < N; ++i) {
18+
total += data[i];
19+
}
20+
return total;
21+
}
22+
23+
extern "C" {
24+
int test_raw() {
25+
int buf[4] = {1, 2, 3, 4};
26+
return sum_raw(buf, 4);
27+
}
28+
int test_array() {
29+
int buf[4] = {1, 2, 3, 4};
30+
return sum_array(buf);
31+
}
32+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// array_vs_carray_host.cpp
2+
// std::array 与 C 数组的零开销对比
3+
4+
#include <array>
5+
#include <cstdint>
6+
#include <iostream>
7+
8+
void size_comparison() {
9+
int raw[4] = {1, 2, 3, 4};
10+
std::array<int, 4> arr = {1, 2, 3, 4};
11+
12+
std::cout << "sizeof(raw) = " << sizeof(raw) << "\n";
13+
std::cout << "sizeof(arr) = " << sizeof(arr) << "\n";
14+
std::cout << "Zero overhead? " << (sizeof(raw) == sizeof(arr) ? "yes" : "no") << "\n";
15+
}
16+
17+
void pass_raw(int ptr[]) {
18+
std::cout << "Inside function: sizeof(ptr) = " << sizeof(ptr) << " (decayed!)\n";
19+
}
20+
21+
void pass_std_array(const std::array<int, 4>& arr) {
22+
std::cout << "Inside function: arr.size() = " << arr.size() << " (safe!)\n";
23+
}
24+
25+
constexpr std::array<uint16_t, 8> crc_table = [] {
26+
std::array<uint16_t, 8> t{};
27+
for (std::size_t i = 0; i < t.size(); ++i)
28+
t[i] = static_cast<uint16_t>(i * 0x1021);
29+
return t;
30+
}();
31+
32+
int main() {
33+
std::cout << "=== std::array vs C array ===\n\n";
34+
size_comparison();
35+
36+
std::cout << "\n--- Decay problem ---\n";
37+
int raw[4] = {10, 20, 30, 40};
38+
std::array<int, 4> arr = {10, 20, 30, 40};
39+
std::cout << "Caller: sizeof(raw) = " << sizeof(raw) << "\n";
40+
pass_raw(raw);
41+
pass_std_array(arr);
42+
43+
std::cout << "\n--- Compile-time table ---\n";
44+
for (std::size_t i = 0; i < crc_table.size(); ++i) {
45+
std::cout << "crc_table[" << i << "] = 0x" << std::hex << crc_table[i] << std::dec << "\n";
46+
}
47+
static_assert(crc_table.size() == 8);
48+
49+
return 0;
50+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// ARM freestanding: compiler options effect demonstration
2+
// Uses only freestanding headers for ARM cross-compilation
3+
// Compare assembly with: -O0, -Os, -O2, -O3
4+
#include <cstddef>
5+
#include <cstdint>
6+
7+
// ---- Simple function: inlining candidate ----
8+
int add_simple(int a, int b) {
9+
return a + b;
10+
}
11+
12+
// ---- Loop: shows loop optimization ----
13+
int accumulate(const int* data, size_t n) {
14+
int sum = 0;
15+
for (size_t i = 0; i < n; ++i) {
16+
sum += data[i];
17+
}
18+
return sum;
19+
}
20+
21+
// ---- Compile-time computation: should disappear at any -O ----
22+
template <int N> constexpr int factorial() {
23+
int result = 1;
24+
for (int i = 2; i <= N; ++i)
25+
result *= i;
26+
return result;
27+
}
28+
29+
constexpr int f10 = factorial<10>();
30+
static_assert(f10 == 3628800);
31+
32+
// ---- Struct with ctor: shows ctor optimization ----
33+
struct TimerConfig {
34+
uint32_t period;
35+
uint32_t prescaler;
36+
uint8_t enabled;
37+
38+
constexpr TimerConfig(uint32_t p, uint32_t ps, bool e)
39+
: period(p), prescaler(ps), enabled(e ? 1u : 0u) {}
40+
};
41+
42+
constexpr TimerConfig default_cfg{1000, 72, true};
43+
static_assert(default_cfg.period == 1000);
44+
45+
// ---- Callable wrappers to observe code generation ----
46+
int call_add() {
47+
return add_simple(3, 4);
48+
}
49+
50+
int call_accumulate() {
51+
const int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
52+
return accumulate(data, 10);
53+
}
54+
55+
int call_factorial() {
56+
return f10;
57+
}
58+
59+
uint32_t call_config() {
60+
return default_cfg.period + default_cfg.prescaler;
61+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <cstdint>
2+
3+
std::uint32_t calculate_baud_divisor_runtime(std::uint32_t cpu_freq, std::uint32_t baud) {
4+
return cpu_freq / (16u * baud);
5+
}
6+
7+
constexpr std::uint32_t calculate_baud_divisor_constexpr(std::uint32_t cpu_freq,
8+
std::uint32_t baud) {
9+
return cpu_freq / (16u * baud);
10+
}
11+
12+
constexpr std::uint32_t divisor = calculate_baud_divisor_constexpr(72000000u, 115200u);
13+
static_assert(divisor == 39u);
14+
15+
std::uint32_t runtime_divisor(std::uint32_t baud) {
16+
return calculate_baud_divisor_runtime(72000000u, baud);
17+
}
18+
19+
std::uint32_t constexpr_divisor() {
20+
return divisor;
21+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// ebo_arm.cpp
2+
// ARM freestanding: 空基类优化 sizeof 对比
3+
4+
#include <cstddef>
5+
6+
struct Empty {};
7+
8+
struct AsMember {
9+
Empty e;
10+
int x;
11+
};
12+
13+
struct AsBase : Empty {
14+
int x;
15+
};
16+
17+
struct WithNoUniqueAddress {
18+
[[no_unique_address]] Empty e;
19+
int x;
20+
};
21+
22+
extern "C" {
23+
std::size_t size_empty() {
24+
return sizeof(Empty);
25+
}
26+
std::size_t size_as_member() {
27+
return sizeof(AsMember);
28+
}
29+
std::size_t size_as_base() {
30+
return sizeof(AsBase);
31+
}
32+
std::size_t size_no_unique() {
33+
return sizeof(WithNoUniqueAddress);
34+
}
35+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// ebo_host.cpp
2+
// 空基类优化与 C++20 [[no_unique_address]]
3+
4+
#include <iostream>
5+
6+
struct Empty {};
7+
8+
struct AsMember {
9+
Empty e; // member: must occupy >= 1 byte
10+
int x;
11+
};
12+
13+
struct AsBase : Empty { // EBO: Empty base costs 0 extra bytes
14+
int x;
15+
};
16+
17+
#if __cplusplus >= 202002L
18+
struct WithNoUniqueAddress {
19+
[[no_unique_address]] Empty e;
20+
int x;
21+
};
22+
#endif
23+
24+
int main() {
25+
std::cout << "sizeof(Empty) = " << sizeof(Empty) << "\n";
26+
std::cout << "sizeof(AsMember) = " << sizeof(AsMember) << " (Empty as member)\n";
27+
std::cout << "sizeof(AsBase) = " << sizeof(AsBase) << " (Empty as base, EBO)\n";
28+
#if __cplusplus >= 202002L
29+
std::cout << "sizeof(WithNoUnique) = " << sizeof(WithNoUniqueAddress)
30+
<< " (C++20 [[no_unique_address]])\n";
31+
#endif
32+
return 0;
33+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <cstddef>
2+
#include <cstdint>
3+
4+
template <std::size_t BlockSize, std::size_t BlockCount> class FixedPool {
5+
struct Block {
6+
alignas(std::max_align_t) std::uint8_t data[BlockSize];
7+
};
8+
9+
Block pool_[BlockCount];
10+
std::size_t free_list_[BlockCount];
11+
std::size_t free_head_;
12+
std::size_t used_count_;
13+
14+
public:
15+
FixedPool() : free_head_(0), used_count_(0) {
16+
for (std::size_t i = 0; i < BlockCount; ++i) {
17+
free_list_[i] = i + 1;
18+
}
19+
free_list_[BlockCount - 1] = static_cast<std::size_t>(-1);
20+
}
21+
22+
void* allocate() {
23+
if (free_head_ == static_cast<std::size_t>(-1)) {
24+
return nullptr;
25+
}
26+
27+
const std::size_t index = free_head_;
28+
free_head_ = free_list_[index];
29+
++used_count_;
30+
return pool_[index].data;
31+
}
32+
33+
void deallocate(void* ptr) {
34+
if (!ptr) {
35+
return;
36+
}
37+
38+
const auto base = reinterpret_cast<std::uintptr_t>(&pool_[0]);
39+
const auto current = reinterpret_cast<std::uintptr_t>(ptr);
40+
const std::size_t index = (current - base) / sizeof(Block);
41+
42+
free_list_[index] = free_head_;
43+
free_head_ = index;
44+
--used_count_;
45+
}
46+
47+
std::size_t used_count() const { return used_count_; }
48+
};
49+
50+
FixedPool<32, 8> pool;
51+
52+
void* allocate_packet_buffer() {
53+
return pool.allocate();
54+
}
55+
56+
void release_packet_buffer(void* buffer) {
57+
pool.deallocate(buffer);
58+
}
59+
60+
std::size_t used_packet_buffers() {
61+
return pool.used_count();
62+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <cstdint>
2+
3+
#define GPIO_PORT_A_C ((volatile std::uint32_t*)0x40020000u)
4+
#define PIN_5_C (1u << 5)
5+
6+
void set_pin_c() {
7+
*GPIO_PORT_A_C |= PIN_5_C;
8+
}
9+
10+
template <std::uint32_t Address> class GPIO_Port {
11+
static volatile std::uint32_t& reg() {
12+
return *reinterpret_cast<volatile std::uint32_t*>(Address);
13+
}
14+
15+
public:
16+
static void set_pin(std::uint8_t pin) { reg() |= (1u << pin); }
17+
};
18+
19+
using GPIOA = GPIO_Port<0x40020000u>;
20+
21+
void set_pin_cpp() {
22+
GPIOA::set_pin(5);
23+
}

0 commit comments

Comments
 (0)