enum + long

L

Laurent Deniau

If I understand well, an enumeration is only garantee to hold at most an
int (6.7.2.2-2). So I would like to know:

how to store a long in an enum?

enum { p2_31 = 1L << 31 };
// boom

how to define a synonym of a constant address?

enum { p = (ptrdiff_t)&address_of_an_unknown_variable };
// boom, ptrdiff_t is generally of type long.

The important aspect is the constness since I would like to use the new
identifier to initialize static data. It is mainly the second case which
interests me, even if both are equivalent.

Note that I cannot use the preprocessor since my problem rises after the
cpp phase. This is why I don't know the variable identifier when I need
to take its address (but I know it when I can define the enum).

Thanks.

a+, ld.
 
E

Eric Sosman

Laurent Deniau wrote On 03/17/06 12:25,:
If I understand well, an enumeration is only garantee to hold at most an
int (6.7.2.2-2). So I would like to know:

how to store a long in an enum?

enum { p2_31 = 1L << 31 };
// boom

An enum constant *is* an int, never a long or a short
or an unsigned int or anything else. Therefore, it is not
possible to define an enum constant whose value is less
than INT_MIN or greater than INT_MAX.

Although the enum constants are ints, the enum type
itself can be any kind of integer the compiler chooses
(but it must choose a type that can represent all the
values of the associated constants). Thus, it is just
possible that in

enum { A, B, C } x;

.... `x' might actually be a long, and you might actually
be able to store a long value in it: `x = LONG_MAX'.
However, there is no portable way to discover exactly
what type the compiler selected for `x', hence no way to
predict whether the assignment will work as desired.
how to define a synonym of a constant address?

enum { p = (ptrdiff_t)&address_of_an_unknown_variable };
// boom, ptrdiff_t is generally of type long.

When you specify a value for an enum constant, you must
use a compile-time constant expression. Addresses are not
compile-time constants.
The important aspect is the constness since I would like to use the new
identifier to initialize static data. It is mainly the second case which
interests me, even if both are equivalent.

Note that I cannot use the preprocessor since my problem rises after the
cpp phase. This is why I don't know the variable identifier when I need
to take its address (but I know it when I can define the enum).

"When you define the enum" must be "when you write the
source code," which in turn must be "before the preprocessor
runs," so I do not understand why the preprocessor cannot do
what you want. What, exactly, are you trying to do?
 
V

Vladimir S. Oka

If I understand well, an enumeration is only garantee to hold at most
an int (6.7.2.2-2). So I would like to know:

how to store a long in an enum?

You can't...
enum { p2_31 = 1L << 31 };
// boom

how to define a synonym of a constant address?

I'm not sure I understand this, but it's late in the day...
enum { p = (ptrdiff_t)&address_of_an_unknown_variable };
// boom, ptrdiff_t is generally of type long.

The important aspect is the constness since I would like to use the
new identifier to initialize static data. It is mainly the second case
which interests me,

Why are you insisting on using `enum` for something that, to me, seems
like a constant pointer? Why an array of these, indexed by an `enum`
won't do (if you still insist on using `enum`)?
even if both are equivalent.

They don't look equivalent to me. `ptrdiff_t` is not guaranteed to be
defined as `long`.
 
L

Laurent Deniau

Eric said:
Laurent Deniau wrote On 03/17/06 12:25,:



An enum constant *is* an int, never a long or a short or an unsigned
int or anything else. Therefore, it is not possible to define an
enum constant whose value is less than INT_MIN or greater than
INT_MAX.

Yes. This is what I was saying. The example above was the goal
(according to the next point which is my real care), not the way to do it.
When you specify a value for an enum constant, you must use a
compile-time constant expression. Addresses are not compile-time
constants.

An enum requires an integral constant expression and the address of a
variable with static storage duration is constant (6.6-9). But it seems
that the conversion to ptrdiff_t break the constness leading to an
invalid expression (i.e. either not constant, either not integral).
"When you define the enum" must be "when you write the source code,"
which in turn must be "before the preprocessor runs," so I do not
understand why the preprocessor cannot do what you want. What,
exactly, are you trying to do?

A bit complex to explain here and showing a code sample would need to
introduce about a hundred of macros manipulating list of tokens and
complex code generation.

In the mean time I decided to completely redesign part of the code to
avoid this problem. But I had to use a union and I don't like to (less
elegant).

a+, ld.
 
K

Kenneth Brody

Laurent said:
Eric said:
Laurent Deniau wrote On 03/17/06 12:25,: [...]
how to define a synonym of a constant address?

enum { p = (ptrdiff_t)&address_of_an_unknown_variable }; // boom,
ptrdiff_t is generally of type long.


When you specify a value for an enum constant, you must use a
compile-time constant expression. Addresses are not compile-time
constants.

An enum requires an integral constant expression and the address of a
variable with static storage duration is constant (6.6-9). But it seems
that the conversion to ptrdiff_t break the constness leading to an
invalid expression (i.e. either not constant, either not integral).

The address of a variable with static storage is a runtime constant.
An enum requires a compile-time constant.

[...]


--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
L

Laurent Deniau

Kenneth said:
Laurent said:
Eric said:
Laurent Deniau wrote On 03/17/06 12:25,:
[...]
how to define a synonym of a constant address?

enum { p = (ptrdiff_t)&address_of_an_unknown_variable }; // boom,
ptrdiff_t is generally of type long.


When you specify a value for an enum constant, you must use a
compile-time constant expression. Addresses are not compile-time
constants.

An enum requires an integral constant expression and the address of a
variable with static storage duration is constant (6.6-9). But it seems
that the conversion to ptrdiff_t break the constness leading to an
invalid expression (i.e. either not constant, either not integral).


The address of a variable with static storage is a runtime constant.
An enum requires a compile-time constant.

I do not catch this point. The terms "runtime constant" or "compile-time
constant" are not part of the norm. Even if I am aware that the address
is computed during the link phase, that is before program runtime but at
a time where the enum does not exist anymore, from the point of view of
the norm I don't see anything which asserts that an address of a
variable with static storage duration is not constant. BTW a such
address is qualified as a "constant address" in the norm and it can be
use to initialize a constant pointer with static storage duration
(6.6-7). In other terms, if the conversion of the constant address into
an integral type would have been the identity, the compiler could have
been able to use the enum as an alias and replace its use by the
corresponding address in the TU. Unfortunately the conversion is not the
identity (my last remark).

a+, ld.
 
K

Kenneth Brody

Laurent said:
Kenneth said:
Laurent said:
Eric Sosman wrote:

Laurent Deniau wrote On 03/17/06 12:25,:
[...]

how to define a synonym of a constant address?

enum { p = (ptrdiff_t)&address_of_an_unknown_variable }; // boom,
ptrdiff_t is generally of type long.


When you specify a value for an enum constant, you must use a
compile-time constant expression. Addresses are not compile-time
constants.

An enum requires an integral constant expression and the address of a
variable with static storage duration is constant (6.6-9). But it seems
that the conversion to ptrdiff_t break the constness leading to an
invalid expression (i.e. either not constant, either not integral).


The address of a variable with static storage is a runtime constant.
An enum requires a compile-time constant.

I do not catch this point. The terms "runtime constant" or "compile-time
constant" are not part of the norm. Even if I am aware that the address
is computed during the link phase, that is before program runtime but at
a time where the enum does not exist anymore, from the point of view of
the norm I don't see anything which asserts that an address of a
variable with static storage duration is not constant.

How about this:

extern int foo;
enum { p = (ptrdiff_t)&foo };
char array[p];
BTW a such
address is qualified as a "constant address" in the norm and it can be
use to initialize a constant pointer with static storage duration
(6.6-7). In other terms, if the conversion of the constant address into
an integral type would have been the identity, the compiler could have
been able to use the enum as an alias and replace its use by the
corresponding address in the TU. Unfortunately the conversion is not the
identity (my last remark).

Suppose that converting an address into an integer causes some sort of
conversion. (One such example would be 16-bit segmented architecture
where pointers are 32 bits, but ints are 16 bits.)

extern int foo, bar;
enum { myfoo = (ptrdiff_t)&myfoo,
mybar = (ptrdiff_t)&bar
} myfoobar;
myfoobar foobar;

...
switch(foobar)
{
case myfoo:
break;
case mybar:
break;
}

What happens in the case where &myfoo and &mybar, when converted to an
int, are identical? Given that this cannot be detected at compile time,
and given that you cannot have identical cases, how would you handle
this?

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:[email protected]>
 
L

Laurent Deniau

Kenneth said:
How about this:

extern int foo;
enum { p = (ptrdiff_t)&foo };
char array[p];

This is the same point I have shown.
Suppose that converting an address into an integer causes some sort of
conversion. (One such example would be 16-bit segmented architecture
where pointers are 32 bits, but ints are 16 bits.)

Then you are in the case of my example where the conversion is not the
identity. My question was why an enum is still an int and not something
representing "a word processor" like the int was intended to be at the
beginning of C.

Then:

extern int foo;
enum { p = (intptr_t)(void*)&foo };
static int *const p_foo = (void*)p;

could be equivalent to:

extern int foo;
static int *const p_foo = &foo;

with no loss of information. Note that it is pure speculation, since in
the meantime I changed my design to get rid of this problem.

a+, ld.
 
A

A. Sinan Unur

My question was why an enum is still an int and not something
representing "a word processor" like the int was intended to be at the
beginning of C.

Huh? Care to explain what you mean by that?

Sinan
 
V

Vladimir S. Oka

A. Sinan Unur opined:

I must quote the great McEnroe: You cannot be serious!
Huh? Care to explain what you mean by that?

Sinan



--
BR, Vladimir

There was a young lady from Prentice
Who had an affair with a dentist.
To make things easier
He used anesthesia,
And diddled her, `non compos mentis'.
 
A

A. Sinan Unur

explain what? about enum or about int?

No, the part about either of them being "a word processor".

However, now that I look at this again, I think you meant "processor
word", but I just was not able to grok it the first time I saw your
message.

Sinan
 
L

Laurent Deniau

A. Sinan Unur said:
No, the part about either of them being "a word processor".

However, now that I look at this again, I think you meant "processor
word", but I just was not able to grok it the first time I saw your
message.

yes sorry, I meant "representing a processor word".

a+, ld.
 

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
474,176
Messages
2,570,947
Members
47,498
Latest member
log5Sshell/alfa5

Latest Threads

Top