静态断言
- C中的断言assert
(1)直接参考:https://www.cnblogs.com/lvchaoshun/p/7816288.html
(2)C的assert是运行时检测发现错误,而不是编译时
(3)C在编译时错误用#error来输出 - C++静态断言
(1)C++引入static_assert(表达式, “提示字符串”)来实现编译时的静态断言
(2)实例演示
#include <iostream>
#include <type_traits>
// 编译期常量表达式
constexpr int factorial(int n) {
return (n <= 1) ? 1 : (n * factorial(n - 1));
}
int main() {
// 编译时断言:检查某些条件是否成立
static_assert(sizeof(int) == 4, "int 类型的大小不是 4 字节");
static_assert(factorial(5) == 120, "Factorial 计算错误");
std::cout << "所有静态断言均通过。" << std::endl;
return 0;
}
#include <iostream>
#include <cassert>
int factorial(int n) {
assert(n >= 0); // 断言n是非负数
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
int main() {
int num1 = 5;
int num2 = -3;
// 正常情况
std::cout << "Factorial of " << num1 << " is " << factorial(num1) << std::endl;
// 异常情况(将触发断言)
std::cout << "Factorial of " << num2 << " is " << factorial(num2) << std::endl;
return 0;
}
- 静态断言主要用途
(1)static_assert主要用于检查模板参数是否符合期望
(2)C++20中引入了concept来进一步更好的实现模板参数的编译时类型匹配检查
内存对齐
- C语言中内存对齐关键点
(1)#pragma 和 attribute((packed)) attribute((aligned(n)))
#include <stdio.h>
// 使用 #pragma pack 控制对齐
#pragma pack(push, 1) // 设置为1字节对齐
typedef struct {
char c;
int i;
double d;
} PackedStruct;
#pragma pack(pop) // 恢复默认对齐
// 使用 __attribute__((packed)) 控制对齐
typedef struct {
char c;
int i;
double d;
} __attribute__((packed)) PackedStructAttribute;
// 使用 __attribute__((aligned(n))) 控制对齐
typedef struct {
char c;
int i;
double d;
} AlignedStruct __attribute__((aligned(16)));
int main() {
PackedStruct ps;
PackedStructAttribute psa;
AlignedStruct as;
printf("Size of PackedStruct: %zu bytes\n", sizeof(PackedStruct));
printf("Size of PackedStructAttribute: %zu bytes\n", sizeof(PackedStructAttribute));
printf("Size of AlignedStruct: %zu bytes\n", sizeof(AlignedStruct));
printf("Address of ps.c: %p\n", (void*)&ps.c);
printf("Address of ps.i: %p\n", (void*)&ps.i);
printf("Address of ps.d: %p\n", (void*)&ps.d);
printf("Address of psa.c: %p\n", (void*)&psa.c);
printf("Address of psa.i: %p\n", (void*)&psa.i);
printf("Address of psa.d: %p\n", (void*)&psa.d);
printf("Address of as.c: %p\n", (void*)&as.c);
printf("Address of as.i: %p\n", (void*)&as.i);
printf("Address of as.d: %p\n", (void*)&as.d);
return 0;
}
- C++中内存对齐新增关键字
(1)alignof (C++11 起) 查询对齐要求
(2)alignas (C++11 起)设置对齐,效果:和__attribute__((aligned(n)))效果一样,往大了设置有用
#include <iostream>
#include <cstddef> // for std::size_t
// 使用 alignas 设置对齐
struct alignas(16) AlignedStruct {
char c;
int i;
double d;
};
// 未对齐的结构体
struct UnalignedStruct {
char c;
int i;
double d;
};
int main() {
// 使用 alignof 查询对齐要求
std::cout << "Alignment of char: " << alignof(char) << std::endl;
std::cout << "Alignment of int: " << alignof(int) << std::endl;
std::cout << "Alignment of double: " << alignof(double) << std::endl;
std::cout << "Alignment of AlignedStruct: " << alignof(AlignedStruct) << std::endl;
std::cout << "Alignment of UnalignedStruct: " << alignof(UnalignedStruct) << std::endl;
// 打印结构体大小
std::cout << "Size of AlignedStruct: " << sizeof(AlignedStruct) << std::endl;
std::cout << "Size of UnalignedStruct: " << sizeof(UnalignedStruct) << std::endl;
// 分配对齐的内存
void* ptr = aligned_alloc(alignof(AlignedStruct), sizeof(AlignedStruct));
if (ptr) {
std::cout << "Memory allocated at address: " << ptr << std::endl;
free(ptr); // 记得释放内存
} else {
std::cerr << "Memory allocation failed!" << std::endl;
}
return 0;
}
- 什么情况下需要人为改变/指定对齐方式
(1)往大去对齐。有时候会有一些硬件特殊要求,譬如MMU,cache等。用__attribute__((aligned(n)))实测ok,用#pragma实测不ok
(2)往下去对齐。有时候需要节省内存而浪费效率,所以希望忽略内存对齐,紧密排放。用#pramgma实测ok,用__attribute__((aligned(n)))实测不ok
总结
了解static_assert的使用方法
了解alignof 、alignas,可以实现内存对齐
学习记录,侵权联系删除。
来源:朱老师物联网大课堂