Matt Gibson Matt Gibson - 6 months ago 8
Swift Question

Should conditional compilation be used to cope with difference in CGFloat on different architectures?

In answering this earlier question about getting a use of

ceil()
on a CGFloat to compile for all architectures, I suggested a solution along these lines:

var x = CGFloat(0.5)

var result: CGFloat

#if arch(x86_64) || arch(arm64)
result = ceil(x)
#else
result = ceilf(x)
#endif

// use result


(Background info for those already confused: CGFloat is a "float" type for 32-bit architecture, "double" for 64-bit architecture (i.e. the compilation target), which is why just using either of
ceil()
or
ceilf()
on it won't always compile, depending on the target architecture. And note that you don't seem to be able to use
CGFLOAT_IS_DOUBLE
for conditional compilation, only the architecture flags...)

Now, that's attracted some debate in the comments about fixing things at compile time versus run time, and so forth. My answer was accepted too fast to attract what might be some good debate about this, I think.

So, my new question: is the above a safe, and sensible thing to do, if you want your iOS and OS X code to run on 32- and 64-bit devices? And if it is sane and sensible, is there still a better (at least as efficient, not as "icky") solution?

Answer

Matt,

Building on your solution, and if you use it in several places, then a little extension might make it more palatable:

extension CGFloat {
    var ceil: CGFloat {
        #if arch(x86_64) || arch(arm64)
            return ceil(x)
        #else
            return ceilf(x)
        #endif
    }
}

The rest of the code will be cleaner:

var x = CGFloat(0.5)
x.ceil
Comments