• 17 pragma


    1 pragma 简介

    • #pragma 用于指示编译器完成一些特定的动作

    • #pragma 所定义的很多指示字是编译器独有的

    • #pragma 在不同的编译器间是不可移植的

      • 预处理器将忽视它所不认识的 #pragma 指令
      • 不同的编译器可能以不同的方式解释同一条 #pragma 指令
    • 一般用法

      • 不同的 parameter 参数语法和意义各不相同
      #pragma parameter
      

    2 #pragma message

    • message 参数在大多数的编译器中都有相似的实现

    • message 参数在编译时输出消息到编译输出窗口

    • message 用于条件编译中可提示代码的版本信息

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

    • #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;
      }
      //编译:gcc -DANDROID40 test.c -o test
      test.c:10: note: #pragma message: Compile Android SDK 4.0...
      //运行结果
      Android 4.0
      

    3 #pragma once

    • #pragma once 用于保证头文件只被编译一次

    • #pragma once 是编译器相关的,不一定被支持

    • #pragma once 使用示例

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

    4 #pragma back

    • 内存对齐

      • 不同类型的数据在内存中按照一定的规则排列,而不一定是顺序的一个接一个的排列
      #include <stdio.h>
      
      struct Test1
      {
          char  c1;
          short s;
          char  c2;
          int   i; 
      };
      
      struct Test2
      {
          char  c1;
          char  c2;
          short s;
          int   i;
      };
      
      int main()
      {
          printf("sizeof(Test1) = %d
      ", sizeof(struct Test1));  //12
          printf("sizeof(Test2) = %d
      ", sizeof(struct Test2));  //8
      
          return 0;
      }
      
    • 为什么需要内存对齐?

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

    • strcut 占用的内存大小

      • 第一个成员起始于 0 偏移处

      • 每个成员按其类型大小和 pack 参数中较小的一个进行对齐

        • 偏移地址必须能被对齐参数整除
        • 结构体成员的大小取其内部长度最大的数据成员作为其大小(仅在计算对齐参数比较时
      • 结构体总长度必须为所有对齐参数的整数倍

    • 编译器在默认情况下按照 4 字节对齐

    • GCC 不支持 #pragma pack(8)

    • 结构体大小计算

      • Demo1
      #include <stdio.h>
      
      #pragma pack(2)
      struct Test1
      {              //对齐参数    偏移地址    大小
          char  c1; //1           0          1
          short s;  //2           1—>2       2
          char  c2; //1           4          1
          int   i;  //2           5->6       4
      };
      #pragma pack()
      
      #pragma pack(4)
      struct Test2
      {
          char  c1;
          char  c2;
          short s;
          int   i;
      };
      #pragma pack()
      
      int main()
      {
          printf("sizeof(Test1) = %d
      ", sizeof(struct Test1));  //
          printf("sizeof(Test2) = %d
      ", sizeof(struct Test2));  //
      
          return 0;
      }
      
      • Demo2
      #include <stdio.h>
      
      #pragma pack(8)
      
      //8字节
      struct S1
      {              //对齐参数    偏移地址    大小
          short a;   //2          0          2
          long b;    //4          2->4       4
      };
      
      //24字节
      struct S2
      {                 //对齐参数    偏移地址    大小
          char c;       //1          0         1
          struct S1 d;  //4          1->4      8
          double e;     //8          12->16    8
      };
      
      #pragma pack()
      
      int main()
      {
          printf("%d
      ", sizeof(struct S1));
          printf("%d
      ", sizeof(struct S2));
      
          return 0;
      }
      
  • 相关阅读:
    IntelliJ Idea 快捷键列表
    mysql索引类型和方式
    基本git指令
    idea中deBug方法
    BeanUtils.copyProperties(A,B)使用注意事项
    MySQL字段类型
    JAVA常识1
    Redis在windows下的安装下载
    Netty
    IDEA工具
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13646494.html
Copyright © 2020-2023  润新知