admin管理员组

文章数量:1122832

I'm running into an issue with a macro that is generated from an environment variable in platform.io:

-D SXM_VERSION=\"${sysenv.SXM_VERSION}\"

As you can see SXM_VERSION forced to start and end with a literal double quote (which is the behavior I want btw!).

But I need to handle the case where the system env var was not set and thus SXM_VERSION literally contains "". When that happens, I want to automatically set it to "0.0.0".

This didn't work because SXM_VERSION is always defined:

#ifndef SXM_VERSION
#define SXM_VERSION "0.0.0"
#endif

And for everything else I tried, I'm getting expression must have integral or enum typeC/C++(847). E.g:

  • #if SXM_VERSION == ""
  • #if SXM_VERSION == '""'
  • #if SXM_VERSION == "\"\""
  • #if defined(SXM_VERSION) && SXM_VERSION[1] == '"'

I'm running into an issue with a macro that is generated from an environment variable in platform.io:

-D SXM_VERSION=\"${sysenv.SXM_VERSION}\"

As you can see SXM_VERSION forced to start and end with a literal double quote (which is the behavior I want btw!).

But I need to handle the case where the system env var was not set and thus SXM_VERSION literally contains "". When that happens, I want to automatically set it to "0.0.0".

This didn't work because SXM_VERSION is always defined:

#ifndef SXM_VERSION
#define SXM_VERSION "0.0.0"
#endif

And for everything else I tried, I'm getting expression must have integral or enum typeC/C++(847). E.g:

  • #if SXM_VERSION == ""
  • #if SXM_VERSION == '""'
  • #if SXM_VERSION == "\"\""
  • #if defined(SXM_VERSION) && SXM_VERSION[1] == '"'
Share Improve this question asked Nov 22, 2024 at 11:14 ForivinForivin 15.5k30 gold badges118 silver badges210 bronze badges 1
  • 3 There are no comparisons between string literals in the C++ preprocessor (only integers as the error message says). You are going to have to look for another way to do whatever it is you are trying to do. The plausible choice would be to move that test to the level where you invoke the compiler. You don't say what shell you are using but most of them allow string comparisons. – john Commented Nov 22, 2024 at 11:16
Add a comment  | 

1 Answer 1

Reset to default 0

C++ in general discourages extensive use of preprocessor. Since this problem is about defining literals, you can benefit from everything that C++ provides in that regard:

   #ifndef SXM_VERSION
   #error "SXM_VERSION compiler macro undefined"
   #else
   #include <string_view>
   using namespace std::literals;
   constexpr auto smx_ver
                = SXM_VERSION[0]
                ? std::string_view{SXM_VERSION}
                : "0.0.0"sv;
  #endif

The smx_ver is practically identical to a constant value macro, except that it is type-safe and unmodifiable. Now you can use this compile-time constant to conditionalize your code:

   #include <type_traits>
   void f(){
       if constexpr(smx_ver)
          g();
       else
          h();
   };

   using my_type = std:: conditional_t
                 < smx_ver=="123"sv
                 , my_123_type
                 , my_oth_type
   >;

本文标签: C preprocessor check if macro equals two double quotesStack Overflow