3

Using #if, #endif in Swift (using Xcode) produces errors if it cuts into the flow of an operation. This screenshot says it all:

Swift #if, #endif error

Does anyone know a solution to make this example work, without repeating the entire code block twice? There can easily be situations where the entire block can be very large.

EDIT: My sample was a bit too simple. Here is a new sample where the "else if" depends on the same define (DEBUG). The "else if" must also be within the #if and #endif. And other samples can be much more complex than this.

enter image description here

5
  • 2
    Unlike of C/Objective C # keywords are parsed not by pre-processor, but by the same parser as the rest of the swift code. So they must follow same syntactic rules and can't just cut into code. Commented Mar 12, 2019 at 15:43
  • Post code instead of screenshots. Commented Mar 12, 2019 at 15:50
  • I hear what you're saying user28434. It is a real limitation. I'm hoping someone has a way to make it work without repeating a large block of code. Commented Mar 12, 2019 at 15:53
  • Dharmesh, I used a screenshot so that it would also show the errors displayed by Xcode. I could have stated the errors, but sometimes a picture just makes things more clear. Commented Mar 12, 2019 at 15:55
  • when I do this, in Xcode 16, the error was: Expected #else or #endif at end of conditional compilation block I think the part about block is where this starts to make sense. Commented Nov 10, 2024 at 4:28

3 Answers 3

6

Ideally, limit the usage of #if as much as possible. Using preprocessor directives is always a bit of a code smell. In this case, you can simply use a boolean variable:

#if DEBUG
let debug = true
#else
let debug = false
#endif

Then simply use the variable:

var a = 0
var b = 0

...

else if debug && a == b {
}

In release mode the code will become unreachable and the optimizer will remove it anyway.

With a bit of imagination, we can find other solutions, for example, we can move the check to a function:

func isDebugCheck(a: Int, b: Int) -> Bool {
   #if DEBUG
      return a == b
   #else
      return false
   #endif
}

or we can move the whole code to a separate function and replace if-else by a return (or continue, depending on you needs), e.g.:

if a == 7 {
  ...
  return
}

#if DEBUG
  if a == b {
     return
  }
#endif

if ...
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Sulthan. I was using a solution something like this. It just seems silly to set up the result of an "if else" before execution actually reaches the "if else". But it looks like there is no other way.
@msedore You can move the ifs to a function and replace if-else by an if-return-else. Or just move the check to a function func isDebugCheck(a, b) { #if DEBUG return a == b #else return false }.
Excellent idea!
2

As @user28434 notes, there is no source-level pre-processor. This has gotten rid of a lot of very tricky pre-processor problems in C (such as bizarre needs for parentheses to make things work).

However, #if is integrated well into the language, and specifically supports switch for exactly these kinds of cases.

var a = 0

#if DEBUG
let b = 0
#endif

switch a {
case 7: a += 1
    #if DEBUG
case b: a += 2
    #endif
case 5: a += 3
default:
    break
}

1 Comment

Thanks, but a switch statement only works because my sample is simple. As I've been trying to say, real-world samples can be a lot more complex, not just comparing a single integer.
1

You can simply achieve this case with below code:

if a == b {
    #if DEBUG
    a += 2
    #else
    a += 1
    #endif
} else if a == c {
    a += 3
}

1 Comment

Thanks for the response. However, that solution won't work if the conditions in the "else if" statement also depend on the same define (DEBUG). My sample was a bit too simple.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.