为什么要为预处理器指令而烦恼? 这个问题似乎是相当基本的,但是从工程学(非计算机科学)的背景来看,我不确定C++代码中的 > < 的片段。

为什么要为预处理器指令而烦恼? 这个问题似乎是相当基本的,但是从工程学(非计算机科学)的背景来看,我不确定C++代码中的 > < 的片段。,c++,c-preprocessor,C++,C Preprocessor,通过快速搜索,我找到了关于预处理器指令的简明、解释良好的教程页面 但是为什么还要为预处理器指令的概念而烦恼呢?是否不可能编写可以为常量赋值、定义子程序/函数/宏和处理错误的等效代码 我想我最终想知道什么时候使用这样的预处理器指令是好的实践,什么时候不是。因为预处理器指令在构建时执行,而您编写的代码将在运行时执行。因此,预处理器指令有效地为您提供了以编程方式修改源代码的能力 注意,C预处理器对于这种事情来说是一种相当粗糙的机制;C++的模板系统为代码的编译时构造提供了更强大的框架。其他语言甚至有更

通过快速搜索,我找到了关于预处理器指令的简明、解释良好的教程页面

但是为什么还要为预处理器指令的概念而烦恼呢?是否不可能编写可以为常量赋值、定义子程序/函数/宏和处理错误的等效代码


我想我最终想知道什么时候使用这样的预处理器指令是好的实践,什么时候不是。

因为预处理器指令在构建时执行,而您编写的代码将在运行时执行。因此,预处理器指令有效地为您提供了以编程方式修改源代码的能力


注意,C预处理器对于这种事情来说是一种相当粗糙的机制;C++的模板系统为代码的编译时构造提供了更强大的框架。其他语言甚至有更强大的元编程功能(例如,Lisp的宏系统)。

答案1:条件代码必须根据它在哪种计算机上工作而有所不同

回答2:启用和禁用编译时看到的语言扩展和兼容性特性


预处理器来自C语言,在C语言中有很多东西是无法表达的。好的C++代码比C代码少使用它的理由,但遗憾的是它并不是很有用。

它被最常用的两个东西,没有它将更难组织:

  • 不同平台的不同代码部分

  • 不,实际上,在所有情况下,没有预处理器是不可能通过的。我最喜欢的宏之一是

    #define IFDEBUG if(DEBUG==1)
    //usage:
    IFDEBUG{
      printf("Dump of stuff:.,,,");
    }else{
      //..do release stuff
    }
    
    如果没有宏,我将在最终的可执行文件中浪费(可能很多)空间


    您还必须认识到,C/C++没有任何类型的包类型
    require
    或其他类似的系统。因此,如果没有预处理器,就无法防止代码重复。(不能包含头文件)

    当需要执行实际应用程序范围之外的操作时,可以使用预处理器指令。例如,您将看到根据构建可执行文件的体系结构进行预处理以包含或不包含代码。例如:

    #ifdef _WIN32 // _WIN32 is defined by Windows 32 compilers
    #include <windows.h>
    #else
    #include <unistd.h>
    #endif
    
    另一个用途是在代码和库中嵌入版本控制

    在Makefile中,您可以看到以下内容:

    -D MY_APP_VERSION=4.5.1
    
    而在你的代码中

    cout << "My application name version: " << MY_APP_VERSION << endl;
    

    <代码> CUT> P>这是一个比没有任何替代品来从C++中获得一些反射能力的工具。 生成具有相同名称的变量和字符串非常有用。

    但是为什么还要为预处理器指令的概念而烦恼呢?是否不可能编写可以为常量赋值、定义子程序/函数/宏和处理错误的等效代码

    <>其在C++中的使用非常低,为了避免与预处理器相关的问题,创建了语言的特征。p> 我想我最终想知道什么时候使用这样的预处理器指令是好的实践,什么时候不是


    在一般的C++源代码中,它通常被视为一个很差的实践——特别是当有一个使用其他语言特征的均值时。某些事情(即平台/构建相关程序和生成性程序)需要它。简言之,通常会有一个可伸缩性好的替代品。(例如常量定义为枚举,或内联模板而不是宏)。如果你发现自己使用了一个,你不确定,那么就问问/寻找是否有更好的方法来声明C++ C++中的代码“THEXCODE代码片段”,而不需要预处理器。

    < P> C预处理器执行许多任务,其中一些但不是所有的都有更好的C++替代方案。其中C++有更好的替代用法。这些替代方案包括模板、内联和
    const
    变量(一种矛盾修饰法,但标准称之为它们)来代替#define宏

    然而,很少有事情是你不想做的,或者根本不能做的<例如,代码>#include是必不可少的,当为多个平台或配置编码时,条件编译仍然很有用(尽管在所有情况下都应谨慎使用)


    在某些情况下,通过
    #pragma
    控制的特定于编译器的扩展可能是不可避免的。

    在编译代码之前进行预处理。这在以下情况下是合适的

    #ifdef WIN32
    #include <something.h>
    #elseif LINUX
    #include <somethingelse.h>
    #endif
    
    原因是您得到了正确的类型转换和数据类型处理

    不是很好,因为你会写

    int i = 5
    int max = MAX(i++, 6);
    
    预处理器将替换为:

    int max = (i++) > (6) ? (i++) : (6);
    
    这显然不会产生预期的结果

    相反,MAX应该是一个函数(而不是宏)。如果是函数,它还可以在参数中提供类型

    我见过用于各种有趣事情的预处理器。比如语言关键字声明。在这种情况下,它有助于提高可读性


    简而言之,对于编译类型必须发生的事情,例如条件includes指令,使用预处理器。避免将其用于常量。避免使用宏,尽可能使用函数。

    通常不应使用预处理器指令。遗憾的是,有时你必须在C和C++中使用.< C最初定义语言的方式是,如果不使用预处理器,您真的无法对它做任何严肃的事情。该语言没有其他内置支持来创建模块化程序、常量、内联代码或进行通用编程

    C++解决了大部分这些问题,但是这个工具仍然存在,所以它仍然被使用。(有趣的是,不是模块化的。我们仍然坚持使用
    #include

    如果你想和一种语言比较
    #define MAX(x,y) (x) > (y) ? (x) : (y)
    
    int i = 5
    int max = MAX(i++, 6);
    
    int max = (i++) > (6) ? (i++) : (6);