墨水屏驱动扫盲:搞懂IL3895的扫描方向和窗口地址设置(避坑指南)
2026/4/21 17:03:43
在C++语言中,宏与constexpr(const),主要于常量和表达式的处理,特别是在编译期计算时,有着重要的作用。很多开发者可能对二者的使用非常多,但二者到底有什么不同可能不是很清楚。或者说,无法清晰的描述出二者的不同,只可意会,无法言传。
下面将对二者在不同的角度进行细节上的区分和说明。
对于宏于常量处理可以从形式和内容、编译期和作用域等角度进行对比,其区别在于:
#definePI3.14159constexprintx=100;doubleret=PI*3;constexprdoubled=x*3;#define PI 3.14 namespace Demo{ #define LEN 10 constexpr int d = 10; } int ret = PI*2; ret = LEN *2; ret = Demo::d *2;#ifdefDEBUG#defineSIGNAL100#else#defineSIGNAL1#endif#defineSTRING(x)#x#defineCONCAT(s1,s2)s1##s2constevalautostr_concat(){returnstd::string_view("hello")+" "+"world";}#defineMUL(x,y)x*y//表达复杂的情况下会出现问题MUL(2+3,10);//=32,期望是50需要赘述一下的是,在C++20以后,扩展了constexpr的应用范围,增加了consteval关键字,这都是对常量(表达式)的一种更广泛的推广应用。大家可紧密的跟踪新标准的中相关说明,不断的扩展自己的眼界。
在前面的文中也反复提到过,在没有特殊的情况下,不建议使用宏,特别是复杂的宏开发。宏与C++的强类型语言本身还是有些相悖的,所以一般都是推荐使用constexpr。同时,constexpr对调试的友好性,也容易在出现问题后便于定位和解决问题。
但宏也有其优势之处,特别是在条件编译和预处理时,constexpr则只能望洋兴叹,力有所不逮。另外,对于控制头文件的重复包含、编译器或硬件平台的特性支持以及一些底层预定义应用的宏,也都是宏应用的优势之处。
下面给出一个对比的例程:
#include<iostream>#include<chrono>#include<array>// 宏#defineSQUARE(x)((x)*(x))// constexprconstexprintconstSquare(intx){returnx*x;}constexprintcompileTest(){constintmRet=SQUARE(5);constexprintcRet=constSquare(5);static_assert(SQUARE(3)==7,"cacl err");//可修改7为9static_assert(constSquare(3)==9,"constexpr cacl err");return0;}intmain(){//编译期测试constexprintret=compileTest();intx=2;intmacRet=SQUARE(x);std::cout<<"cur cacl ret is:"<<ret<<","<<macRet<<std::endl;//编译期和运行期计算constexprintcSquare=constSquare(2);intrSquare=constSquare(x);std::cout<<"cur cacl ret is:"<<cSquare<<","<<rSquare<<std::endl;//加和计算inty=3;intsumRet=SQUARE(x+y);intcSumRet=constSquare(x+y);std::cout<<"cur cacl ret is:"<<sumRet<<","<<cSumRet<<std::endl;return0;}十八般武器各有各的优势,长得相近的武器未必就可以互相替代。哲学上不是有句名言么,“存在即合理”。宏和constexpr就是这种情形。在一个好的开发者的眼中,只有最合适的方法,没有最优的方法。至于如何选择宏和constexpr,多吃几回亏就好了。