zoukankan      html  css  js  c++  java
  • #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用于指定内存对齐方式
  • 相关阅读:
    Cassandra vs. HBase
    游戏留存率分析
    Writing a Discard Server
    t
    启动进程 派生 关闭而不关闭
    单页应用 SAP Vue
    TiDB 整体架构 结合yarn zookeeper分析架构
    Writing a Simple YARN Application 从hadoop生态抽出yarn ,单独使用yarn
    Phoenix put the sql back in NoSql
    事件序列化器 Flume 的无数据丢失保证,Channel 和事务
  • 原文地址:https://www.cnblogs.com/yanyun888/p/9213145.html
Copyright © 2011-2022 走看看