You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的表达式)的场景:

  1. 当宏未定义时:

    • #ifndef _LIBCPP_VERSION 条件为真,进入对应分支
    • #if !_LIBCPP_VERSION 中,未定义的宏在#if表达式里会被当作0处理,!0结果为1,条件也为真,此时两者行为一致
  2. 当宏被定义为非0值时:

    • #ifndef条件为假,进入else分支
    • #if !_LIBCPP_VERSION 中,非0值取反后为0,条件也为假,两者行为仍一致
  3. 当宏被定义为0时:

    • #ifndef _LIBCPP_VERSION 条件为假(因为宏已经被定义了),进入else分支
    • #if !_LIBCPP_VERSION 中,!0结果为1,条件为真,进入第一个分支,此时两者行为完全相反

简单来说,#ifndef只关心宏是否存在,而#if !MACRO不仅关心宏是否存在,还会判断宏展开后的值是否为0。只有当宏要么未定义,要么被定义为非0值时,两者才会表现出相同的行为;如果宏被定义为0,结果就会不一样。

内容的提问来源于stack exchange,提问作者Khurshid Normuradov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 03:20:51