C/C++标准中#if !宏与#ifndef宏是否始终等价?
#if !_LIBCPP_VERSION与#ifndef _LIBCPP_VERSION是否始终等价? 我发现一段代码在三大主流编译器中都能正常运行且无报错:
#include <cstdio> int main() { #if !_LIBCPP_VERSION std::printf("_LIBCPP_VERSION not defined"); #else std::printf("_LIBCPP_VERSION defined and equal to %d", _LIBCPP_VERSION); #endif #ifndef _LIBCPP_VERSION std::printf("_LIBCPP_VERSION not defined"); #else std::printf("_LIBCPP_VERSION defined and equal to %d", _LIBCPP_VERSION); #endif }
我的问题是:在C或C++标准中,#if !_LIBCPP_VERSION这种检查是否始终与#ifndef _LIBCPP_VERSION等价?
回答
两者并不始终等价,差异出现在宏被定义为0(或展开后结果为0的表达式)的场景:
当宏未定义时:
#ifndef _LIBCPP_VERSION条件为真,进入对应分支#if !_LIBCPP_VERSION中,未定义的宏在#if表达式里会被当作0处理,!0结果为1,条件也为真,此时两者行为一致
当宏被定义为非0值时:
#ifndef条件为假,进入else分支#if !_LIBCPP_VERSION中,非0值取反后为0,条件也为假,两者行为仍一致
当宏被定义为0时:
#ifndef _LIBCPP_VERSION条件为假(因为宏已经被定义了),进入else分支#if !_LIBCPP_VERSION中,!0结果为1,条件为真,进入第一个分支,此时两者行为完全相反
简单来说,#ifndef只关心宏是否存在,而#if !MACRO不仅关心宏是否存在,还会判断宏展开后的值是否为0。只有当宏要么未定义,要么被定义为非0值时,两者才会表现出相同的行为;如果宏被定义为0,结果就会不一样。
内容的提问来源于stack exchange,提问作者Khurshid Normuradov
相关产品推荐
相关产品推荐

