Operators '.' and '->' in a constant expression

F

frank

Do the structure operators '.' and '->' have any possible employment
in constant expressions? I try;

const struct astruct {int x; int y; } as = { 1, 2 };

int aa=as.y;

and Microsoft's compiler tells me;
zak.c(3) : error C2099: initializer is not a constant

I would guess these operators would have to refer to a variable, so
they would never be useable in a constant initialiser, but is there
any way of using 'const' keyword or other method whereby they would be
relevant?
 
F

frank

Do the structure operators '.' and '->' have any possible employment
in constant expressions? I try;

const struct astruct {int x; int y; } as = { 1, 2 };

int aa=as.y;

and Microsoft's compiler tells me;


I would guess these operators would have to refer to a variable, so
they would never be useable in a constant initialiser, but is there
any way of using 'const' keyword or other method whereby they would be
relevant?

to which the short answer is yes, because you can have

struct astruct {int x; int y[3]; } as = { 1, { 2, 3, 4 } };

int *aa=as.y;

sorry for useless post.
 
J

Jack Klein

Do the structure operators '.' and '->' have any possible employment
in constant expressions? I try;

const struct astruct {int x; int y; } as = { 1, 2 };

int aa=as.y;

and Microsoft's compiler tells me;


I would guess these operators would have to refer to a variable, so
they would never be useable in a constant initialiser, but is there
any way of using 'const' keyword or other method whereby they would be
relevant?

In C, the value of an object is not a compile-time constant
expression, even if the object itself has a 'const' qualifier.

One way around this is to use an enumeration, when the value is a
signed int, or a macro no matter what the type of the value is:

#define AS_Y_VAL 2

....or:

enum { AS_Y_VAL = 2 };

Then:

const struct astruct {int x; int y; } as = { 1, AS_Y_VAL };

int aa = AS_Y_VAL;
 
F

frank

In C, the value of an object is not a compile-time constant
expression, even if the object itself has a 'const' qualifier.

One way around this is to use an enumeration, when the value is a
signed int, or a macro no matter what the type of the value is:

#define AS_Y_VAL 2

...or:

enum { AS_Y_VAL = 2 };

Then:

const struct astruct {int x; int y; } as = { 1, AS_Y_VAL };

int aa = AS_Y_VAL;

What I'm trying to figure out is whether the struct operators '.' and
'->' have any applicability / usefulness in a constant initialiser. I
have established that with;

struct astruct {int x; int y[3]; } as = { 1, { 2, 3, 4 } };

int *aa=as.y;

the operator '.' can be used in a constant initialiser. However I
cannot see any possible example where the operator '->' can be used in
a constant initialiser. Can you think of such an example?
 
E

Emmanuel Delahaye

Do the structure operators '.' and '->' have any possible employment
in constant expressions? I try;

const struct astruct {int x; int y; } as = { 1, 2 };

int aa=as.y;

and Microsoft's compiler tells me;


I would guess these operators would have to refer to a variable, so
they would never be useable in a constant initialiser, but is there
any way of using 'const' keyword or other method whereby they would be
relevant?

Make it static.

static const struct astruct {int x; int y; } as = { 1, 2 };

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++
 
F

frank

(e-mail address removed) wrote on 05/06/05 :

Make it static.

static const struct astruct {int x; int y; } as = { 1, 2 };

that doesn't change anything.... if I have

static const struct astruct {int x; int y; } as = { 1, 2 };

int aa= as.x;

then Microsoft still gives

zak.c(5) : error C2099: initializer is not a constant

besides which, I have an example for '.' and it's now an example for
'->' which I seek
 
E

Emmanuel Delahaye

that doesn't change anything.... if I have

static const struct astruct {int x; int y; } as = { 1, 2 };

int aa= as.x;

then Microsoft still gives

zak.c(5) : error C2099: initializer is not a constant

besides which, I have an example for '.' and it's now an example for
'->' which I seek

Actually, this works with Dev-C++ (gcc) and Borland C++ 3.1:

#include <stdio.h>

int main (void)
{
struct astruct
{
int x;
int y;
}
as =
{
1, 2
};

int aa = as.y;

printf ("aa=%d\n", aa);
return 0;
}

Can you post the exact snippet that is not working.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.
 
M

Michael Mair

Emmanuel said:
Actually, this works with Dev-C++ (gcc) and Borland C++ 3.1:

#include <stdio.h>

int main (void)
{
struct astruct
{
int x;
int y;
}
as =
{
1, 2
};

int aa = as.y;

printf ("aa=%d\n", aa);
return 0;
}

Can you post the exact snippet that is not working.

The OP probably is trying to do that on file level, not within
a function block -- then you need a constant initialiser for aa
and run into trouble. Alternatively give aa static storage
duration.

Cheers
Michael
 
F

frank

The OP probably is trying to do that on file level, not within
a function block -- then you need a constant initialiser for aa
and run into trouble. Alternatively give aa static storage
duration.

Yes, exactly. If you do the initialisation "int aa = as.y;" within a
function then it is computed at runtime, so it is not a constant
initialiser. If you do it at global level then it is done at compile
time hence must be a constant initialiser.

I can't think of any way of employing -> operator in a constant
initialiser. I need an example to test some code. It may simply be
impossible to do in C.
 
C

CBFalconer

Do the structure operators '.' and '->' have any possible
employment in constant expressions? I try;

const struct astruct {int x; int y; } as = { 1, 2 };

int aa=as.y;

and Microsoft's compiler tells me;


I would guess these operators would have to refer to a variable,
so they would never be useable in a constant initialiser, but is
there any way of using 'const' keyword or other method whereby
they would be relevant?

"const" in C does not mean constant, it means "read only". To get
a compile time constant you need to use #define, or an identifier
specified in an enum statement, as in:

enum things {THING1, THING2, THING3);

you can also control their values, as in:

enum things {THING1 = 10, THING2 = 100, THING3 = 1000);
 
C

Chris Torek

[vertically compressed]

Yes, exactly. If you do the initialisation "int aa = as.y;" within a
function then it is computed at runtime, so it is not a constant
initialiser. If you do it at global level then it is done at compile
time hence must be a constant initialiser.

For the exact rules, see the ANSI C standards. Note that C99 has
more latitude than C89. In particular, while C89 permits non-constant
initializers for scalars, it requires constants for aggregates. This
constraint is removed in C99. (For instance:

void f(int x, int y) { int a[2] = { x, y }; ... }

is legal in C99 but not in C89. This may seem a bit odd given that:

void f(int x, int y) { int a0 = x, a1 = y; ... }

is OK in both; but it is still true.)
I can't think of any way of employing -> operator in a constant
initialiser. I need an example to test some code. It may simply be
impossible to do in C.

% cat t.c
struct S { int arr[10]; };
struct S obj;
#define pobj (&obj)
int *p = pobj->arr;
% cc -ansi -pedantic -O -W -Wall -c t.c
%

(Note, again, that the C99 rules under which *& cancel are "better"
than those for C89; but gcc, at least, thinks this is OK, and without
poring over the C89 standard, I think so to.)
 
F

frank

% cat t.c
struct S { int arr[10]; };
struct S obj;
#define pobj (&obj)
int *p = pobj->arr;
% cc -ansi -pedantic -O -W -Wall -c t.c
%

(Note, again, that the C99 rules under which *& cancel are "better"
than those for C89; but gcc, at least, thinks this is OK, and without
poring over the C89 standard, I think so to.)

That's great, thank you.
 
L

Lawrence Kirby

On Sun, 05 Jun 2005 21:40:07 +0000, Chris Torek wrote:

....
I can't think of any way of employing -> operator in a constant
initialiser. I need an example to test some code. It may simply be
impossible to do in C.

% cat t.c
struct S { int arr[10]; };
struct S obj;
#define pobj (&obj)
int *p = pobj->arr;
% cc -ansi -pedantic -O -W -Wall -c t.c
%

(Note, again, that the C99 rules under which *& cancel are "better"
than those for C89; but gcc, at least, thinks this is OK, and without
poring over the C89 standard, I think so to.)

This is fine, the it never reads the value of an object. &obj is the
address of an object with static storage duration which is a constant
expression (&obj)->arr designates the "value" of which is a pointer to the
first element of the array. This is again the address of a static object
and the contents of the array was never acessed.

You can also get plenty of constant expressions using sizeof e.g.

sizeof p->m

whih works even if p is an automatic variable.

Lawrence
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top