-1

May be this is duplicate, I can't find similar question.

My surprise that, following code works for all three big compiler without error

#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
}

Link to godbolt

My question is that: There check #if !_LIBCPP_VERSION - is always similar with #ifndef _LIBCPP_VERSION by standard C or C++?

markalex
  • 8,623
  • 2
  • 7
  • 32
  • 4
    No it's not always the same. `#if !_LIBCPP_VERSION` will be true if `_LIBCPP_VERSION` is defined to `0` (but `#ifndef _LIBCPP_VERSION` will not). – wohlstad Feb 08 '23 at 18:23
  • @wohlstad See Link, all Gcc, Clang, Msvc success compiled `#if !_LIBCPP_VERSION` even _LIBCPP_VERSION not defined. – Khurshid Normuradov Feb 08 '23 at 18:25
  • 4
    That does not contradict what I wrote. Try to use `#define _LIBCPP_VERSION 0` and you'll get a different behavior between the two. I.e. they are not always the same. – wohlstad Feb 08 '23 at 18:27

1 Answers1

2

They are not equivalent for numerical values.

SOME_MACROS #if !SOME_MACROS #ifndef SOME_MACROS
x True False
1 False False
0 True False
undef True True

Now, you said you only care about numerical values, so only the middle rows are relevant here. Yet we see a difference in those two rows.

ikegami
  • 367,544
  • 15
  • 269
  • 518