473,396 Members | 2,010 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Converting enums to pointers

I have a class that's holding a list of pointers to pointers. It is an
implementation of an open addressed hashmap. It is homework, but I only
want help on this specific issue. Please do not tell me anything about
hashmaps, just about this small problem. Suppose I want to have an
enumeration that describes various states that a slot can have besides
having contents.

enum SpecStates { EMPTY = 0, DELETED = -1 };

However, the array that holds the information is an array of 'Record*'s. I
cannot assign EMPTY or DELETED to a slot without an explicit type cast (
(Record*) EMPTY ), since it involves a jump from int to Record*, which is
taken to be from int to void* to Record*. This is ugly and, perhaps,
suboptimal.

I have also considered

const Record* EMPTY = (Record*) 0;
const Record* DELETED = (Record*) 1;

But if I do that I have lost all the convenience of the enumerated type.

What is the correct way to accomplish what I am trying to do, assuming I
want no major design changes (for instance, I want no wrapper for the
Record, since, although that would work, it does not preserve the simplicity
I am seeking)?

James
Jul 22 '05 #1
6 1828
James Aguilar wrote:
const Record* EMPTY = (Record*) 0;
You declare EMPTY to be a null pointer here. This is legitimate.
const Record* DELETED = (Record*) 1;
This is implementation defined and may not universally work. Nothing
guarantees you can reinterpret cast an arbitrary integer to a pointer type.
But if I do that I have lost all the convenience of the enumerated type.

const Record DELETED;
would work, of course it allocates an unused Record object.
Jul 22 '05 #2
"Ron Natalie" <ro*@sensor.com> wrote in message news:4169e0e1$0$28244
James Aguilar wrote:

const Record* EMPTY = (Record*) 0;


You declare EMPTY to be a null pointer here. This is legitimate.
const Record* DELETED = (Record*) 1;


This is implementation defined and may not universally work. Nothing
guarantees you can reinterpret cast an arbitrary integer to a pointer

type.

But if I do that I have lost all the convenience of the enumerated type.

const Record DELETED;
would work, of course it allocates an unused Record object.


This is a fine solution, though it might be nice to use the extern keyword.
If you say

// a.cpp
const Record DELETED;
void a(std::vector<Record*>& v) {
v.push_back(&DELETED);
}

// b.cpp
const Record DELETED;
void b(std::vector<Record*>& v) {
v.push_back(&DELETED);
}

// main.cpp
#include "a.h"
#include "b.h"
int main() {
std::vector<Record*>& v;
a(v);
b(v);
}

then even though v[0] and v[1] are both deleted records, they have different
addresses and don't compare equal (ie. because we're comparing two different
pointers).

In other words, it is not safe to compare v[N] to &DELETED or &EMPTY to see
if the record is deleted or empty.

To get around this problem we could declare DELETED and EMPTY as extern.

// Record.h
class Record { ... };
extern const Record DELETED;

// Record.cpp
#include "Record.h"
const Record DELETED;

We could also make DELETED a static member of class Record (in which case we
don't need the extern keyword as class static variables are extern anyway),
though that seems a more sylistic issue.
Jul 22 '05 #3
Ron Natalie wrote:
James Aguilar wrote:
const Record* EMPTY = (Record*) 0;


You declare EMPTY to be a null pointer here. This is legitimate.


Yes, and it doesn't actually need a cast.
const Record* DELETED = (Record*) 1;


This is implementation defined and may not universally work. Nothing
guarantees you can reinterpret cast an arbitrary integer to a pointer
type.


And nothing guarantess that the resulting pointer value is not one that
points to an existing object.
But if I do that I have lost all the convenience of the enumerated type.

const Record DELETED;
would work, of course it allocates an unused Record object.


Jul 22 '05 #4
"Rolf Magnus" <ra******@t-online.de> wrote in message
news:ck*************@news.t-online.com...
const Record* DELETED = (Record*) 1;


This is implementation defined and may not universally work. Nothing
guarantees you can reinterpret cast an arbitrary integer to a pointer
type.


And nothing guarantess that the resulting pointer value is not one that
points to an existing object.


Oh, suppose that 1 is never to be dereferenced by the design and works only
as a flag? Is that guaranteed to work? I never actually want to look at
what's at 0x00000001, I just want to use it as a tag to say "This is not a
value you can use". Actually, in my implementation, I use '-1' for that,
not '1'. Is this a valid practice?
Jul 22 '05 #5
James Aguilar wrote:
Oh, suppose that 1 is never to be dereferenced by the design and works only
as a flag? Is that guaranteed to work?


No! There is no guarantee you can convert any arbitrary integer to a
pointer. The only things that are guaranteed to work is an constant
0 (which converts to the null pointer) and the value of a valid pointer
value that was converted to some implementation defined "large enough"
integer type.
Jul 22 '05 #6
"James Aguilar" <jf**@cec.wustl.edu> wrote:
> const Record* DELETED = (Record*) 1;

This is implementation defined and may not universally work. Nothing
guarantees you can reinterpret cast an arbitrary integer to a pointer
type.

Oh, suppose that 1 is never to be dereferenced by the design and works only
as a flag? Is that guaranteed to work? I never actually want to look at
what's at 0x00000001, I just want to use it as a tag to say "This is not a
value you can use". Actually, in my implementation, I use '-1' for that,
not '1'. Is this a valid practice?


Some systems cause a hardware exception when you point to an address
that isn't aligned correctly (1 is hardly likely to have correct
alignment for a Record structure).

Other systems cause a hardware exception if you point to an
invalid address, or an address outside your process space.

You're less likely to get trouble with 1 than -1 (-1 will probably
be an invalid address on just about every system), and less
likely again to get trouble with sizeof(Record) instead of 1.

If you are writing a throwaway application then you could do
this "hack" but I would not recommend it for portable code.
Jul 22 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Joseph Suprenant | last post by:
I have an array of unsigned chars and i would like them converted to an array of ints. What is the best way to do this? Using RedHat 7.3 on an Intel Pentium 4 machine. Having trouble here, hope...
13
by: SpaceCowboy | last post by:
I recently got into a discussion with a co-worker about using enums across a dll interface. He wanted to use chars instead, argueing that depending on compiler settings the size of an enum could...
2
by: Faisal | last post by:
Can anyone tell me if it is possible to enumerate through all the Enums within a class . I have a class with many Enums and would like to accees the Enums through an array/collection etc. I can't...
3
by: Ozzy Knox | last post by:
I am trying to convert a string or int variable to an Enum that I have set up in my C# application. I have tried many options with no success. Any advice would be appreciated. Regards Ozzy
2
by: Harag | last post by:
I need to set multiple Fontsyle enums individually but so far I have found that you can only set a Fontyle on creation of a new Font. My one other option is to build a function to to select...
3
by: Pete Davis | last post by:
I've never done this in C# so I don't know what the appropriate way of doing it is. I've got an array of bytes and I need to convert the array into "usable" data. For example, the first 4 bytes...
4
by: Martin Pritchard | last post by:
Hi, I'm working on a project that historically contains around 40 enums. In the database various fields refer to the int values of these enums, but of course ref integrity is not enofrced and...
2
by: Simon Elliott | last post by:
I have some legacy C++ code which requires some enums to be 1 or 2 bytes in size. I'd ideally like to be able to specify that a few carefully selected enums are a particular size. By default,...
11
by: Marc Gravell | last post by:
This one stumped me while refactoring some code to use generics... Suppose I declare an enum MyEnum {...} Is there a good reason why MyEnum doesn't implement IEquatable<MyEnum> ? Of course,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.