#pragma使用分析

Posted yanyun888

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#pragma使用分析相关的知识,希望对你有一定的参考价值。

#pragma简介

  • #pragma用于指示编译器完成一些特定的动作
  • #pragma所定义的很多指示字是编译器特有的
  • #pragma在不同的编译器间是不可移植的
    • 预处理器将忽略它不认识的#pragma指令
    • 不同的编译器可能以不同的方式解释同一条#pragma指令
  • 一般用法:
    • #pragma parameter

注:不同的parameter参数语法和意义各不相同

#pragma message

  • message参数在大多数的编译器中都有相似的实现
  • message参数在编译时输出消息到编译器输出窗口中
  • message用于条件编译中可提示代码的版本信息

与#error和#warning不同,#pragma message仅仅代表一条编译消息,不代表程序错误

#include <stdio.h>  
  
#if defined(android20)  
    #pragma message("Compile Android SDK 2.0...")  
    #define VERSION "Android 2.0"  
#elif defined(ANDROID23)  
    #pragma message("Compile Android SDK 2.3...")  
    #define VERSION "Android 2.3"  
#elif defined(ANDROID40)  
    #pragma message("Compile Android SDK 4.0...")  
    #define VERSION "Android 4.0"  
#else  
    #error Compile Version is not provided!  
#endif  
  
int main()  
{  
    printf("%s
", VERSION);  
  
    return 0;  
}  

#pragma once

  • #pragma once用于保证头文件只被编译一次
  • #pragma once是编译器相关的,不一定被支持

技术分享图片

这两种方式有什么区别?

通过宏可以保证头文件里的内容只被嵌入一次但可能包含了多次,预处理
器依然处理了多次,所以从效率上说它要打折扣,而pragam once 告诉
预处理器当前文件只被编译一次(即只被include一次,多余的都不会处理),所以它的编译效率会高很多,然而大多数工程使用#ifndef方式,原因在于不是所有的编译器都支持once这个参数,#ifndef是C语言所支持的

例子1:#pragma once使用分析

global.h

#pragma once
int g_value = 1;

main.c

#include<stdio.h>
#include"global.h"
#include"global.h"
int main()
{
    printf("g_value = %d
",g_value);
    return 0;
}

在有的编译器上支持,有的不支持

实际工作中往往使用如下的方式保证移植性和高效性

#ifndef _GLOBAL_
#define _GLOBAL_

#pragma once

int g_var = 1;
#endif

#pragma pack

  • 什么是内存对齐
    • 不同类型的数据在内存中按照一定的规则排列
    • 而不一定是顺序的一个接一个的排列

技术分享图片

12/8

  • 为什么需要内存对齐
    • CPU对内存的读取不是连续的,而是分块读取的
      块的大小只能是1、2、4、8..字节
    • 当读取操作的数据未对齐,则需要两次总线周期来访问内存,因此性能会大打折扣
    • 某些硬件平台只能从规定的相对地址处读取特定类型的数据,否则产生硬件异常
  • #pragma pack用于指定内存对齐方式
    #pragma pack能够改变编译器的默认对齐方式

  • struct占用的内存大小
    • 第一个成员起始于0偏移处
    • 每个成员按照其类型大小和pack参数中较小的一个进行对齐
      偏移地址必须能被对齐参数整除,结构体成员的大小取其内部长度最大的数据成员作为其大小
    • 结构体长度必须为所有对齐参数的整数倍

技术分享图片

小结

  • #pragma用于指示编译器完成一些特定的动作
  • #pragma所定义的很多指示字都是编译器特有的
    • #pragma message 用于自定义编译消息
    • #pragma once用于保证头文件只被编译一次
    • #pragma pack用于指定内存对齐方式

以上是关于#pragma使用分析的主要内容,如果未能解决你的问题,请参考以下文章

#pragma使用分析

Additinal Dependencies和#pragma comment(lib,"*.lib")的分析

#pragma

oc-09-#pragma mark指令的使用,用于查找代码

#pragma mark指令

关于 pragma使用