ts101 #工作记录 #c/c++ #学习
在 构建一个 Hello World 项目 中我们分析到了编译器在编译的时候会使用到 -char-size-32 -double-size-32 来设置数据类型的大小.
在此我们对常用的数据类型大小进行检查和评估.
- int short char long float double
- struct 的大小分配问题
未修改项目配置
```c typedef struct { char a; short b; int c; long d; long long e; double f; float g; } TestSize;
void testSizeOf() {
printf("Test the sizeof for every type\n");printf("char: %d\n", sizeof(char));printf("short: %d\n", sizeof(short));printf("int: %d\n", sizeof(int));printf("long: %d\n", sizeof(long));printf("unsigned char: %d\n", sizeof(unsigned char));printf("unsigned short: %d\n", sizeof(unsigned short));printf("unsigned int: %d\n", sizeof(unsigned int));printf("unsigned long: %d\n", sizeof(unsigned long));printf("float: %d\n", sizeof(float));printf("double: %d\n", sizeof(double));printf("long double: %d\n", sizeof(long double));printf("TestSize: %d\n", sizeof(TestSize));
}
输出结果:<br />
<a name="AL8Gz"></a>
# 修改配置项
- 修改项目中char 类型为 8bits
- **Project -> Project Options -> Processor** , 设置为 8 bit
<br />运行之前的程序, 出现如下结果. 通过对内存分析可知,在 char 和 int 类型中都做了补零操作
Test the sizeof for every type char: 1 short: 2 int: 4 long: 4 unsigned char: 1 unsigned short: 2 unsigned int: 4 unsigned long: 4 float: 4 double: 4 long double: 8 TestSize: 32

<a name="wd8tL"></a>
# 各种结构体的长度测试
下面我们对数据结构进行多次修改并看其长度
- 长度 8
```c
typedef struct {
char a;
short b;
int c;
} TestSize;
typedef struct {
short a;
char b;
char c;
char d;
} TestSize;
长度 4
typedef struct { char a; short b; } TestSize;typedef struct { short a; char b; char c; } TestSize;typedef struct { char b; char c; } TestSize;长度12
typedef struct { char a; short b; int c; long d; } TestSize;长度 16
typedef struct { char a; short b; char z; int c; int d; } TestSize;typedef struct { long long a; long long b; } TestSize;typedef struct { long long a; int b; } TestSize;typedef struct { long long a; int b; int c; } TestSize;长度24
typedef struct { char a; short b; int c; long d; long long e; } TestSize;typedef struct { char a; short b; int c; long long e; int d; } TestSize;typedef struct { char a; char z; short b; int c; long long e; int d; } TestSize;typedef struct { long long a; int b; int c; int d; } TestSize;长度 32
typedef struct { char a; // 1, 2 [实际,占用] short b; // 2, 2 char z; // 1,4 int c; // 4,8 long long e; // 8, 8 int d; // 4,8 } TestSize;
结论:
- 使用 longlong 之后数据都是按照8字节对齐的,不够的地方会补 0 .
- 使用 int, short,char 则是按照 4字节对齐, 在dsp 中最小的就 是 4字节这个不可以调整.
根据我们的使用情况都是两个short 类型数据,可以采用4 字节对齐方式建立结构体方便取数据.
研究开发手册调整对齐模式
Help -> Contents 打开帮助手册

- Manuals -> Software Tool Manuals -> TigerSHARC … -> … -> Compiler -> C/C++ Compiler Language Extensions -> Pragmas -> Data Alignment Pragmas 讲述了如何控制对齐模式.
- 下面有两个语法
```c
// 将下一行按照指定数字对齐 1 代表4 bit
pragma align 4
pragma alignment_region (2)
<a name="GhRWS"></a>
## pragma align
> 下面是使用说明的译文
此 pragma 可在变量和字段声明之前使用。它适用于紧跟在 pragma 后面的变量或字段声明。pragma 的作用是将下一个变量或字段声明在 num 指定的边界上对齐。
- 如果将pragma应用于局部变量,则由于局部变量存储在堆栈上,因此只有当num不大于堆栈对齐(即4个字)时,才会更改变量的对齐方式。如果num大于堆栈对齐方式,则会发出警告,提示忽略pragma。
- 如果num大于以下变量或字段声明通常要求的对齐方式,则变量或字段声明的对齐方式将更改为num。
- 如果num小于通常需要的对齐方式,则变量或字段声明的对齐方式将更改为num,并发出警告,表示对齐方式已减少。
```c
typedef struct {
#pragma align 4
int foo;
int bar;
#pragma align 4
int baz;
} aligned_ints;
- 在本例中,任何声明为aligned_ints类型的对象的foo和baz成员都在四字边界上对齐。这个结构的大小是八个字,在bar和baz之间有两个未使用的字,在结构的末尾有三个填充字。在字节寻址模式下,要对齐的NUM参数必须是16而不是4,因为要对齐的参数是以可寻址单位表示的。
【在 8位 模式下这个 struct 还是 12 字节 及 3 个字, 下面是在 8位模式的测试, 也正好符合上面标红语句的内容】
typedef struct {
#pragma align 4
int foo;
int bar;
#pragma align 8
int baz;
} aligned_ints;
// 长度 16
pragma alignment_region
这个只拷贝样例了, 这个由两个部分组成 alignment_region 和 alignment_region_end. 范围内的数据将都按照指定num进行对齐. 同样在 8位模式下 这个数字应该是 4 的整数倍.
#pragma align 4
int aa; /* alignment 4 */
int bb; /* alignment 1 */
#pragma alignment_region (2)
int cc; /* alignment 2 */
int dd; /* alignment 2 */
int ee; /* alignment 2 */
#pragma align 4
int ff; /* alignment 4 */
int gg; /* alignment 2 */
int hh; /* alignment 2 */
#pragma alignment_region_end
int ii; /* alignment 1 */
#pragma alignment_region (1)
long double jj; /* alignment 1, but the compiler warns
about the reduction */
#pragma alignment_region_end
#pragma alignment_region (3)
long double kk; /* the compiler faults this, alignment is not
a power of two */
#pragma alignment_region_end
不论如何修改还是长度为 24 字节, 即在 8字节处对齐, 结构体内尽量使用相同长度的数据类型进行定义, 方便使用功能
typedef struct {
#pragma align 4
int b; // 4,4
#pragma align 4
int c; // 4,4
#pragma align 4
int d;// 4,8
long long a; //8,8
} TestSize;
word 单位说明
一个 word 应该是 4 字节
当我这只 char 为 8 位时, num 代表的含义将是 1 字节
系统内建的数据类型
对系统内建的一些数据类型进行测试, 这样可以方便代码在不同c 程序之间的复用
printf("__uint8: %d\n", sizeof(__uint8));
printf("__uint16: %d\n", sizeof(__uint16));
printf("__uint32: %d\n", sizeof(__uint32));
printf("__uint64: %d\n", sizeof(__uint64));
printf("__int8: %d\n", sizeof(__int8));
printf("__int16: %d\n", sizeof(__int16));
printf("__int32: %d\n", sizeof(__int32));
printf("__int64: %d\n", sizeof(__int64));
定义自己的通用数据类型
下面是 types.h 文件定义的通用数据类型, 为后面的代码迁移提供便利
// 用于对库中的函数的公开性进行区分
#define PUBLIC
#define PRIVATE static
// 常用数据类型定义
typedef __uint8 UINT8;
typedef __uint16 UINT16;
typedef __uint32 UINT32;
typedef __uint64 UINT64;
typedef __int8 INT8;
typedef __int16 INT16;
typedef __int32 INT32;
typedef __int64 INT64;
struct 的大小说明
Within a structure, members of the fundamental types are aligned on a multiple of their size. Structures are aligned on the strictest alignment of any of their members, but are always aligned to at least 32 bits. As always, the size of a structure is a multiple of its alignment, so this last restriction leads to subtle differences from C implementations on Windows and UNIX® platforms. For example, struct A { short a; short b; short c; }; sizeof(struct A) // is 8 not 6 !!!. Entire variables are aligned to at least 32 bits. They are more strictly aligned if their type requires it. Entire array variables are aligned to 128 bits.
结构体必须按照 32bit 对齐
