user2138149
user2138149

Reputation: 17416

XCode: Initializer element is not a compile-time constant

I am writing a program in C using XCode. I don't use C much, usually I use C++. I've never used XCode before.

Compile error is quite simple, the following lines of code are not being treated as compile time constants by the compiler.

const double PI = 4.0 * atan(1.0);
const double TAU = 8.0 * atan(1.0);

I'm sure this is allowed in C++ 11, although I can't be certain, since I last used it some months ago.

My guess is that the XCode compiler / the C standard does not allow constants to be computed in this way.

Is there an alternative I can use? I don't much fancy the "define" alternative...

#define PI 4.0 * atan(1.0);

As this will (may?) cause unnecessary run-time overhead.

Upvotes: 1

Views: 4903

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 727077

the following lines of code are not being treated as compile time constants by the compiler.

The compiler is right, because they are not compile-time constants: they both make calls to the runtime portion of the Standard C library.

I don't much fancy the "define" alternative...

That's right, #define is not an alternative, because it would force a constant to be re-evaluated in each expression that you have it.

Is there an alternative I can use?

Sure - you can use M_PI for a definition of the π constant *, and 2*M_PI for the TAU:

const double TAU = 2 * M_PI;

I'm sure this is allowed in C++ 11

This is correct: unlike C, C++ does not requite initializers to be compile-time constants.

How is it that calling atan() isn't allowed, but the mathematical operation 2 * M_PI is allowed?

This is because the standard requires compilers to perform all numeric operations on constant expressions during the compile time. However, a single runtime call, such as atan(...), will "poisons" the whole thing, so the compiler will evaluate as much as it can, but the expression will remain a runtime expression, not a compile-time constant.

* It is not standard, but many libraries define it anyway.

Upvotes: 3

Adam Rosenfield
Adam Rosenfield

Reputation: 400682

This is not allowed in C. Unlike C++, C requires global variables to be initialized by compile-time constants. atan(1.0) is not a compile-time constant because it requires calling the function atan() at runtime.

The simple solution is don't call atan(), just us the actual numeric values of pi and tau as your initializers:

const double PI = 3.141592653589793;
const double TAU = 2*PI;

Some math libraries also provide the constant M_PI for you already, so you can just that:

const double PI = M_PI;

but that's not standard C (C89 or C99), so don't rely on all implementations having that constant.

Upvotes: 1

Related Questions