initializer element is not constant

S

Scott

Hi All,

I have the following C code in a header file, outside of any functions:

const float X = 50;
const float Y = 100 * X;

But, when compiling, I get an error:

initializer element is not constant

Why is this? What is the best way to fix the problem (which is that I
want to define a number of constants, and that each constant depends on a
specific constant themselves, and these constants should be in their own
header file)?

Thanks for any help.

Best,
Scott
 
C

Chris Torek

I have the following C code in a header file, outside of any functions:

const float X = 50;
const float Y = 100 * X;

But, when compiling, I get an error:

initializer element is not constant

Why is this?

Unlike most modern high-level languages, C does not have constants.
The "const" keyword means "variable, but if you can, please try to
make it read-only".

Of course, this is an overstatement; C does in fact have some kinds
of constants, such as 50 (which you might want to write as 50.0 or
even 50.0f to make it have type double or float respectively). It
even has symbolic "int"-valued constants, which are spelled "enum".
But it has no symbolic floating-point constants.
What is the best way to fix the problem (which is that I
want to define a number of constants, and that each constant depends on a
specific constant themselves, and these constants should be in their own
header file)?

Use "#define" In this case:

#define X (50.0f)
#define Y (100.0f * X)

would do the trick. Note that #define'd macros are just expanded as
literal text, so it is often important to parenthesize them (as in
this case, at least for Y -- you can get away without it for X).

Because "#define"s do not obey most of C's syntax rules at all (though
they do obey lexical rules, mostly), you can create programs worthy
of entry into the Obfuscated C Code contests with ugly stuff like:

#define LBRACKET [
#define LBRACE {
#define RPAREN )

int a LBRACKET 4 ];
int main (void RPAREN LBRACE
/* ... put some code here ... */
return 0;
}

Do not abuse macros in this fashion (except to scare other C
programmers :) ).
 
R

Ralmin

Scott said:
I have the following C code in a header file, outside of any functions:

const float X = 50;
const float Y = 100 * X;

But, when compiling, I get an error:

initializer element is not constant

Why is this? What is the best way to fix the problem (which is that I
want to define a number of constants, and that each constant depends on a
specific constant themselves, and these constants should be in their own
header file)?

The problem is that "const" variables are not allowed in constant
expressions. You can get around this using macros temporarily. After you
assign the values of the macros to your const variables, you can undefine
the macros.

Untested code:

#define TEMP_X 50
#define TEMP_Y (100 * TEMP_X)

const float X = TEMP_X;
const float Y = TEMP_Y;

#undef TEMP_X
#undef TEMP_Y
 
R

Ralmin

Scott said:
I have the following C code in a header file, outside of any functions:

const float X = 50;
const float Y = 100 * X;

But, when compiling, I get an error:

initializer element is not constant

Why is this? What is the best way to fix the problem (which is that I
want to define a number of constants, and that each constant depends on a
specific constant themselves, and these constants should be in their own
header file)?

The problem is that "const" variables are not allowed in constant
expressions. You can get around this using macros temporarily. After you
assign the values of the macros to your const variables, you can undefine
the macros.

Untested code:

#define TEMP_X 50
#define TEMP_Y (100 * TEMP_X)

const float X = TEMP_X;
const float Y = TEMP_Y;

#undef TEMP_X
#undef TEMP_Y
 
R

Ralmin

Scott said:
I have the following C code in a header file, outside of any functions:

const float X = 50;
const float Y = 100 * X;

But, when compiling, I get an error:

initializer element is not constant

Why is this? What is the best way to fix the problem (which is that I
want to define a number of constants, and that each constant depends on a
specific constant themselves, and these constants should be in their own
header file)?

The problem is that "const" variables are not allowed in constant
expressions. You can get around this using macros temporarily. After you
assign the values of the macros to your const variables, you can undefine
the macros.

Untested code:

#define TEMP_X 50
#define TEMP_Y (100 * TEMP_X)

const float X = TEMP_X;
const float Y = TEMP_Y;

#undef TEMP_X
#undef TEMP_Y
 
R

Ralmin

Scott said:
I have the following C code in a header file, outside of any functions:

const float X = 50;
const float Y = 100 * X;

But, when compiling, I get an error:

initializer element is not constant

Why is this? What is the best way to fix the problem (which is that I
want to define a number of constants, and that each constant depends on a
specific constant themselves, and these constants should be in their own
header file)?

The problem is that "const" variables are not allowed in constant
expressions. You can get around this using macros temporarily. After you
assign the values of the macros to your const variables, you can undefine
the macros.

Untested code:

#define TEMP_X 50
#define TEMP_Y (100 * TEMP_X)

const float X = TEMP_X;
const float Y = TEMP_Y;

#undef TEMP_X
#undef TEMP_Y
 
X

xarax

Chris Torek said:
Unlike most modern high-level languages, C does not have constants.
/snip/
The nearest you can get to a constant symbol
is an enum element:

typedef enum my_constants
{
foo = 50,
bar = 100 * foo
} MyConstants;

const float X = (float) foo;
const float Y = (float) bar;
 
C

Chris Torek

/snip/
The nearest you can get to a constant symbol is an enum element:

Indeed (as I said in the part you snipped :) ... although I did not
elaborate).
typedef enum my_constants
{
foo = 50,
bar = 100 * foo
} MyConstants;

You do not need the typedef, the enumeration type name, and the
"MyConstants" part:

enum { foo = 50, bar = 100 * foo };

works just as well here. Note that 100 * 50 = 5000, which is OK,
but if we went for 100 * 500 (or 50000), we might run into problems
on machines with an INT_MAX of 32767 (16-bit systems).
const float X = (float) foo;
const float Y = (float) bar;

These are fine, of course, but neither X nor Y are constants. C
is a funny language: "const" means "variable", "typedef" means "do
not define a type", and "static" has nothing to do with electricity
or AM-radio noise. :) To get int-valued constants, we can use
"enum"; to define types, we can use "struct"; and to keep function
names local, we can use "static". If those three keywords were
named "const", "type", and "local", things might be much less
confusing. :)
 
C

Chris Croughton

These are fine, of course, but neither X nor Y are constants. C
is a funny language: "const" means "variable", "typedef" means "do
not define a type", and "static" has nothing to do with electricity
or AM-radio noise. :) To get int-valued constants, we can use
"enum"; to define types, we can use "struct"; and to keep function
names local, we can use "static". If those three keywords were
named "const", "type", and "local", things might be much less
confusing. :)

Even worse, "static" is overloaded to mean two different things:

static int x; /* x is local to this translation unit */

void func(void)
{
static int y; /* y does not change between invocations of func */
...
}

The first should have been called 'local', the latter is correctly
called 'static' (meaning "doesn't move", as opposed to automatic
variables which do (or at least can) move in different invocations of
the function).

(C++ redefines 'const' to what the OP wanted, a constant value with a
type, but also alters the meaning of 'struct' to create a type directly
and to basically be a class with members public by default. And still
has the C meanings of 'static'. You'd have thought that they could have
got rid of the ambiguities in writing a new language...)

Chris C
 
S

Scott

Use "#define" In this case:

#define X (50.0f)
#define Y (100.0f * X)

would do the trick. Note that #define'd macros are just expanded as
literal text, so it is often important to parenthesize them (as in
this case, at least for Y -- you can get away without it for X).

Thanks very much! I will give this a try.

Best,
Scott
 
O

Old Wolf

Chris said:
Even worse, "static" is overloaded to mean two different things:

static int x; /* x is local to this translation unit */

void func(void)
{
static int y; /* y does not change between invocations of func */
...
}

In both cases, the variable is local to the scope it's declared in,
and it does not change between invocations of func. I think the
meaning of 'static' is the same in both cases.
The first should have been called 'local', the latter is correctly
called 'static' (meaning "doesn't move", as opposed to automatic
variables which do (or at least can) move in different invocations of
the function).

'x' does not move.
 
C

Chris Croughton

'x' does not move.

Automatic variables, however, do move, and they are also local to the
scope in which they are declared (they can't be anything else). So

static int x;

can't move, the purpose of 'static' is to say "local to the translation
unit" as opposed to

int xx;

which also can't move but is visible outside the translation unit.

Whereas in

void func(void)
{
static int y;

the variable is always local to the function, but 'static' means "always
in the same place" as opposed to

int yy;

which is also local to the function but which will be in a (potentially)
different location each time func() is invoked.

Clearer now? There is only one reason to use static at file scope, and
that is to make the variable local to that file; there is only one
reason to use static at function scope, and that is to force the
variable to keep its position and value between invocations.

Chris C
 
B

Barry Schwarz

Hi All,

I have the following C code in a header file, outside of any functions:

const float X = 50;
const float Y = 100 * X;

But, when compiling, I get an error:

initializer element is not constant

Why is this? What is the best way to fix the problem (which is that I

const means that the VARIABLE in question will not be modified after
it is initialized during its definition. A CONSTANT is a value that
is provided in the source to the compiler. The two are not the same.
want to define a number of constants, and that each constant depends on a

Best is a very imprecise term. One common solution is to use #define,
in your example this would be
#define X 50
and then your definition of Y would work.
specific constant themselves, and these constants should be in their own
header file)?

A header should not define any objects or functions. It should only
declare their types. What happens when two source files that are part
of the same program #include the same header that contains object
definitions?

Macros, on the other hand, can be defined in headers with no trouble.


<<Remove the del for email>>
 
L

Lawrence Kirby

Automatic variables, however, do move, and they are also local to the
scope in which they are declared (they can't be anything else). So

static int x;

can't move, the purpose of 'static' is to say "local to the translation
unit" as opposed to

int xx;

which also can't move but is visible outside the translation unit.

Whereas in

void func(void)
{
static int y;

the variable is always local to the function, but 'static' means "always
in the same place" as opposed to

Really it means "Exists for the lifetime of the program" which implies
that it is always in the same place within a single program invocation,
because objects can't move during their lifetime.
int yy;

which is also local to the function but which will be in a (potentially)
different location each time func() is invoked.

That is true, and it is a result of the fact that yy is only live for the
respective invocation, and there is no relationship between yy's for
different invocations. yy is an automatic variable i.e. it is created
automatically as and when it is required. Note that as C defines this it
doesn't occur at the function level, it is at the block level, except
for objects containing VLAs in C99 which are at the "scope" level. For
example

for (i = 0; i < length; i++) {
char ch;
...
}

while it is likely that ch has the same address on each iteration of the
loop it isn't guaranteed. Also at the start of each loop the value of ch
is indeterminate.
Clearer now? There is only one reason to use static at file scope, and
that is to make the variable local to that file; there is only one
reason to use static at function scope, and that is to force the
variable to keep its position and value between invocations.

And also potentially an initial value at the start of the first
invocation.

Lawrence
 
D

Dave Thompson

On Mon, 17 Jan 2005 10:53:48 +0000, Chris Croughton
(C++ redefines 'const' to what the OP wanted, a constant value with a

Only for constant-initialized integers and enumerations, which latter
are distinct from integers in C++ though not in C. Other C++ const
objects are like C read-only but not usable at compile time.

Admittedly the two things you most commonly need to be constant
expressions are array bounds (in C89 and C++), integer, and case
labels, integer or enumeration.
type, but also alters the meaning of 'struct' to create a type directly
and to basically be a class with members public by default. And still
has the C meanings of 'static'. You'd have thought that they could have
got rid of the ambiguities in writing a new language...)

To be precise, the C89 meanings of 'static' plus two (arguably one)
more, but not (yet?) the other new one added by C99.

"It can't be a new C-family standard if it doesn't add new meanings to
static." <G>

- David.Thompson1 at worldnet.att.net
 
E

E. Robert Tisdale

Scott said:
I have the following C code in a header file, outside of any functions:

const float X = 50;
const float Y = 100 * X;

But, when compiling, I get an error:

initializer element is not constant

Why is this?

It is a design flaw in the C computer programming language
which was fixed in the design of the C++ programming languge
but not in C because it would break existing programs.
What is the best way to fix the problem
(which is that I want to define a number of constants
and that each constant depends on a specific constant themselves
and these constants should be in their own header file)?

#define X (50)
const float Y = 100*X;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top