2

I have following code

static constexpr bool condition = true;

int square(int num) {
    if constexpr (condition) {
      return num * num;
    } else {
      x
      return num;
    }
}

int main() {
    return square(3);
}

compiled with

-std=gnu++17

My assumption for

if constexpr (condition)

was that during compilation the part

    } else {
      x
      return num;
    }

get discarded and I get no error about the undefined

x

Is my understanding wrong that this 'if constexpr' is something like

#ifdef CONDITION
  return num * num;
#else
  x
  return num;
#endif

How do I modify this code that I can compile this?

Enlico
  • 23,259
  • 6
  • 48
  • 102
ge45mue
  • 677
  • 8
  • 23

2 Answers2

8

How do I modify this code that I can compile this?

To fix your code, simply remove the line with x.

Is my understanding wrong that this 'if constexpr' is something like [...]

Yes, your understanding is wrong. From cppreference:

Outside a template, a discarded statement is fully checked. if constexpr is not a substitute for the #if preprocessing directive.

This means every branch in an if constexpr block must be valid C++, even if it's never going to be used.

lubgr
  • 37,368
  • 3
  • 66
  • 117
  • Would it be correct to say that it must be syntactically correct but it's allowed to be semantically incorrect? – Enlico Mar 07 '21 at 22:26
  • Not sure. You are mixing two things here - "syntactically correct" is something that can be evaluated in an objective, strict way. Whether something is "semantically correct" depends on your understanding of the problem domain, the APIs you use etc., so that part is rather blurry. – lubgr Mar 08 '21 at 07:26
  • So probably I'm misusing those terms. I refer to the fact that the non-taken branch can be also non compilable as long as it is valid C++. So in some way it has to be "valid" at some level though it can be not valid at another level. I was guessing what those two levels are. I asked if those two levels are syntax and semantics and you say no, so do they have a name? – Enlico Mar 08 '21 at 07:41
  • I've asked [a new question](https://stackoverflow.com/q/66526165/5825294), if you're interested. – Enlico Mar 08 '21 at 08:03
-2

As you've observed, you can't have "garbage code" like that x codeline inside of a if constexpr clause.

The major advantage of having if constexpr instead of #if is that if constexpr is able to reason about types in a way that the preprocessor wasn't able to. This advantage is often exploited within templates.

For example, you could do something like the following:

template <typename T>
T squareOnlyInt(T num) {
    if constexpr (std::is_same<T,int>::value) {
      return num * num;
    }
    else {
      return num;
    }
}
Cow Corporation
  • 399
  • 2
  • 7