GCC 内存对其选项、警告、其他方式对其

*** gcc 对其选项 [-fpack-struct]

gcc -fpack-struct[=n]

该编译器选项解决了结构中字节对齐问题。

-fpack-struct将所有结构成员无缝隙地压缩在一起。因为它使代码程序效率大大降低,且结构成员的偏移量与系统库不相符,这么做有时可能导致寻址错误,所以一般不使用这个选项。

原文:

-fpack-struct[=n]
Without a value specified, pack all structure members together without holes. When a value is specified (which must be a small power of two), pack structure members according to this value, representing the maximum
alignment (that is, objects with default alignment requirements larger than this are output potentially unaligned at the next fitting location.

Warning: the -fpack-struct switch causes GCC to generate code that is not binary compatible with code generated without that switch. Additionally, it makes the code suboptimal. Use it to conform to a non-default
application binary interface.

***gcc -Wpadded 检测字节是否对齐

#include<stdio.h>

struct my {

char *name;
int age;
} my_details;

int main() {
struct my person1;
return 0;
}

编译

gcc -Wpadded -fpack-struct=8 -o test /tmp/test.c

会收到警告,因为 int 4个字节。

*** 其他方式对齐

#ifdef __cplusplus
extern "C" {
#endif

// 以下代码是用来字节对齐使用的
#ifndef WIN32
#ifndef __GNUC__
#define __PACKED__
#pragma options align=packed
#else
#define __PACKED__ __attribute__ ((packed))
#pragma pack(push,1)
#endif
#else
#define __PACKED__
#pragma pack(push,1)
#endif

***********************

struct TestStruct4
{
char a;
long b;
};

***********************

#ifndef WIN32
#ifndef __GNUC__
#pragma options align=reset
#else
#pragma pack(pop)
#endif
#else
#pragma pack(pop)
#endif

#ifdef __cplusplus
}
#endif

或者:

#pragma pack(8)

struct TestStruct4
{
char a;
long b;
};

#pragma pack()

使用指令#pragma pack (n),编译器将按照n 个字节对齐。
使用指令#pragma pack (),编译器将取消自定义字节对齐方式。

但是文件一定要按照C的方式,使用 extern "C" {}选项。

**** 网上其他摘要

http://blog.chinaunix.net/uid-25808509-id-2426501.html?_t=t

注意别的#pragma pack 的其他用法:
#pragma pack(push) //保存当前对其方式到packing stack
#pragma pack(push,n) 等效于 #pragma pack(n)
#pragma pack(n) //n=1,2,4,8,16 保存当前对齐方式,设置按n 字节对齐
#pragma pack(pop) //packing stack 出栈,并将对其方式设置为出栈的对齐方

【pack 结果与 OS 相关】
默认的内存对齐方式以及内存对齐规则在不同的系统上是有区别的,所以GCC编译器在这一点上在不同的系统上也是区别对待的。
虽然到现在也没有看到GCC在Linux系统下的使用 #pragma pack(N) 的内存对齐规则,
但是从我测试的结果来看是这样:默认的对齐是按照 int 型(4字节)对齐,如果指定 #pragma pack(N) 中的 N 的话,N 不能大于默认对齐指定的长度,即如果默认对齐是 4 的话,N的取值可以是 1、2、4,超过 4 之后作为 4 处理。
在 Windows 等系统上似乎没有这个限制。

原文地址:https://www.cnblogs.com/20170722-kong/p/12129053.html

时间: 2024-10-09 02:53:30

GCC 内存对其选项、警告、其他方式对其的相关文章

fopen警告处理方式

warning C4996: “fopen”被声明为否决的 问题:vs2005中编程时,遇到如下: warning C4996: “fopen”被声明为否决的. 解释:微软的警告,主要是那些都是C库的函数,很多函数内部是不进行参数检测的(包括越界类的),微软担心使用这些会造成内存异常,所以就改写了一 下同样功能的函数,只不过进行了参数的检测,使用这些新的就可以了.不用特意记,每个函数在给出警告时都会告诉你相应的安全函数,注意一下警告信息就可以了,使用时再 查看一下MSDN.库函数改写例子: mk

GCC编译命令常用选项

GCC是GUN Compiler Collection的简称,除编译程序外,还包含其他相关工具.GCC可将高级语言编写的源代码构建成计算机直接执行的二进制代码.GCC是Linux平台下最常用的编译程序,也是Linux平台编译器的事实标准.GCC支持四十余种不同目标体系结构(如X86系列.ARM及PowerPC等),可运行在不同的操作系统上(如Linux.Solaris及Windows等).GCC既支持基于宿主的开发(即在A平台上编译该平台使用的程序),也支持交叉编译(即在A平台上编译供B平台使用

进程间的八种通信方式----共享内存是最快的 IPC 方式

1.无名管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系通常是指父子进程关系. 2.高级管道(popen):将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们成为高级管道方式. 3.有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信. 4.消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识

【连接】gcc和gdb常用选项

gcc:http://www.cnblogs.com/ggjucheng/archive/2011/12/14/2287738.html#_Toc311642844 gdb:http://www.cnblogs.com/ggjucheng/archive/2011/12/14/2288004.html [连接]gcc和gdb常用选项,布布扣,bubuko.com

解决编译GCC内存不足的错误

近期在使用阿里和腾讯的云服务器,由于只是测试用所以只租用了廉价512的内存,在编译gcc时遇到错误,表面上看只是编译错误,并且原因不明,纠结了几次之后猜测应该是由于系统资源不足导致的,所以尝试增加系统的swap分区,这里需要检查两个地方 一.修改swappiness 1.查看你的系统里面的swappiness$ cat /proc/sys/vm/swappiness不出意外的话,你应该看到是 60,在阿里云看到的可能是0,那么就需要修改2.修改swappiness值$ sudo sysctl v

[转组第8天] | 变量在内存中的位置和访问方式

2018-05-05 <C++反汇编和逆向技术>第七章 变量在内存中的位置和访问方式 读书笔记 1.全局变量和局部变量的区别 全局变量属于进程作用域,也就是说,在整个进程中都能够访问到这个全局变量.静态变量属于文件作用域,在当前源码文件内可以访问到:局部变量属于函数作用域,在函数内部可以访问到:在"{}"语句块内定义的变量,属于块作用域,只能在定义变量的"{}"快内访问到. 全局变量在内存中的地支顺序是先定义的变量在低地址,后定义的变量在高地址. 全局变

经典!GCC常用的操作选项

gcc 简单讲解和常用参数解析 .a  静态库 (archive)   .c  C源代码(需要编译预处理)   .h  C源代码头文件     .i  C源代码(不需编译预处理) .o  对象文件        .s  汇编语言代码 .so 动态库 $gcc -g -Wall hello.c -o hello  -Wall   开启编译器几乎所有常用的警告 -g  表示在生成的目标文件中带调试信息  -o  后面为指定生产的机器码的文件名 $ gcc -Wall hello.c hello_fn

gcc编译代码报错及编译方式

一.error: 'for' loop initial declarations are only allowed in C99 mode 前段时间写了一个小C程序,放在linux下用gcc编译出错,弹出以下错误: 百度后才知道,是gcc的模式问题. 我在for循环里习惯直接定义并初始化变量来使用: for(int i=0:i<length: i++) 而在gcc编译时是错误的,应该在循环外定义变量: int i; for(i = 0; i<length; i++) 这样才编译通过. 这是因为

Linux下gcc、objdump、file命令使用方式总结

一.GCC编译器和常用命令 gcc编译器不仅支持c语言,还支持Ada.C++.Objective-C语言.一般编译的过程可以分为四个阶段:预处理(Preprocessing).编译(Compilation).汇编(Assembly)和连接(Linking) 1.  一步到位的编译指令 包含四个阶段 gcc test.c –o test 2.  预处理 将头文件内容插入到test.c文件,-E是预处理结束后停止,并输出预处理结果 gcc –E test.c –o test.i 3.  编译 对.i