By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,671 Members | 1,633 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,671 IT Pros & Developers. It's quick & easy.

Cast to a type idntified by a number?

P: 4
I suppose my problem really started when I decided to implement a top-down design, because management always wants to see the frosting before they let you bake a cake. In any case, I now seem to have the proverbial design that is simple, elegant... and wrong.

Before I give up, I'd like to see if anyone in this forum has a solution.

I seems that I need to perform a run-time cast to a type that is specified by an integer. Ideally, the integer comes from a dynamic list of types, that is created by appending "plain old data" (POD) types and derived types. But, I can live with a fixed enumeration of types. (e.g. 1 = char, 2 = int, 3 = long, 4 = myType, ... etc.

In any case, I ultimately come down to a need to downcast a base pointer to a derived type, using a number to identify the type. Or, I could cast a void pointer ( or a char pointer, if it helps ) to the identified type.

I understand that RTTI could help me, but only if I loop through the list of types to find the correct one. ( If there is a cast_to_type_of_TypeID, please let me know. ) However, the target of my project is embedded controllers and I am concerned about the overhead of RTTI. If RTTI could actually do such a cast, I would prefer to simply adapt the method and minimize the overhead.

I expect to make use of templates, but not the STL. Both the STL and RTTI make use of exception handling. I cannot use this in my system as it is generally not supported by compilers for embedded processors ( with good reason ).

For an example, assume I have a class that contains the data < typNum, dataAddr > where typNum is an integer and dataAddr is the address of a data value that matches the specified type.
Using instances of this class, I'd like to write:
A = B * C; // Or, perform other operations.
- or -
f(A) = f(B) * f(C); // f() is some conversion operator.

It seems that any operator ( function, macro, other? ) that I apply to B or C can potentially perform the correct cast within the function, but it cannot return it. So, back at the ( B * C ) level, nothing is gained.

Is there any way to accomplish this ( in C or C++ )?

I have seen the Boost libraries and spent some time looking at the "any" and "variant" classes. I'm far from a complete understanding, but I don't think that they solve my problem.

Thanks for any suggestions,
Reid
Feb 3 '08 #1
Share this Question
Share on Google+
3 Replies


weaknessforcats
Expert Mod 5K+
P: 9,197
There is a design pattern called State.

In that pattern a object appears to change its type. This would be where your typecast comes in.

However, do not typecast in C++. When you do it means one of two things: a) you are calling relic C code with stuff like void* arguments, or b) your C++ design is screwed up.

So forget the cast.

Also forget RTTI. If you have to ask what type, then you don't know what you are doing.

Instead, read this article from the C/C++ HowTos forum http://www.thescripts.com/forum/thread660060.html.

I believe your solution is there.
Feb 4 '08 #2

P: 4
Oops! Accidentally posted a copy before I was done.
Please see the following post.
Feb 11 '08 #3

P: 4
Thanks for your suggestions, but I don't think they address the issue I tried to describe. Apparently, I failed to properly convey my question.
The state machine example is nice, but has little relevance to my issue.

You are correct that my experience with C++ is limited. But, I have been writing embedded C applications for 25 years and was an avid student of C++ for many years, as it evolved. Unfortunately, I have had little opportunity to use it professionally, or even in my spare time.

You may also be correct that I should re-evaluate my C++ design.
It is in fact that evaluation process that led to my question.

While developing my design, I encountered what seems to me to be either a missing capability of the language, or an inability on my part to grasp some basic concept.

I suspect that some context might help with the explanation.
I am developing an application framework for programming embedded controllers. A typical controller might have 250K of code space, 35K of RAM and 2 K of non-volatile memory. No keyboard. No monitor. No disk drives. No file system. Effectively, no operating system, as you might know it. It probably has some hardware-specific digital and analog inputs and outputs and a communications port (typically a CAN bus).

The C++ STL arrays, vectors, collections, etc. are useless to me because they are designed in a way that essentially requires garbage collection. Embedded application programs run indefinitely. With limited memory resources, unrestricted use of "new" and "delete" fragments and consumes memory. This happens easily when a vector is copied by deleting memory and allocating new memory of a random size.

Garbage collection is not a practical solution because the entire application runs in an infinite loop that must (deterministically) repeat at a fixed rate. There is simply no time for random garbage collection. A better solution is a system that keeps and re-uses everything it allocates. (I'm sure there's a name for this technique, but I've forgotten it.)

Imagine a system that allocates most memory once, at power-up. What happens if allocation occurs by inserting elements into lists, one at a time. If each list frees its memory and copies itself to a new, larger location with each insertion, memory is fragmented before power-up is completed.

My plan includes creation of a "Data Directory" within the controller that contains references to all of the data values. Each lists contains references to different types of values, including other lists. This is analogous to a windows hierarchy of folders and files, but is instead composed of "lists" and "values".

The instances of data values are in a managed set of "hidden" lists. Each hidden lists contains instances of a uniform value type (all int, all long, etc.).

The "references" contained in all the Data Directory lists are also all of a uniform type. They are not a C++ style reference, but are instead instances of a class that includes member values indicating the type number and instance number of a value. For clarity, I will call it a "TypInstRef". In this way, the same value instance can be referenced at multiple points in the Data Directory hierarchy.

One of the many advantages of this design is that all functions in the application have an identical signature. Each function accepts one TypInstRef as an argument and returns void. Since the TypInstRef argument can reference a list, the function has access to any desired hierarchy of values. This also makes it very easy to make lists of functions. The list of functions can be executed sequentially. The list can even be dynamic, so each pass through the list executes a different set of functions. (This capability makes creation of state machines a trivial exercise. Likewise for event handling.)

Ultimately, it would be very nice for me if I could easily convert any TypInstRef into the actual value instance and type that it represents. Most functions that use these lists as arguments will simply execute math equations and comparison logic. I cannot afford to execute an iterative loop on each value of every equation, to determine its type. I have a number that indicates the data type. I can assure that it is consistent with the data. And, I can access the data, at least by address. It is frustrating that I can't see how to simply tell it to be what it is.

A key capability to make this design work is creation of a list of mixed types. It seems to me that this is possible only by up-casting all of the list elements to a common base class. (Not so different from casting the address to void pointer, in the C language.) In any case, the type identification is lost. It can be recovered only by a down-cast back to the actual type. This is where I have been struggling.

My latest thought (of many) is to use the TypInsRef class as a base for derived classes (of IntInstRef, LongInstRef etc). Then each function could cast its arguments to their intended types and manipulate the instance values directly, rather than having a local shadow copy of all the data. (Ugh! That would be like passing a data structure by value.)

Even if that works, the code will not be very pretty. I agree with your sentiment about casting. I would prefer to avoid it. But, if I can't I prefer to encapsulate it in a way that it can be tested and validated to assure that it causes no harm.

It sure would be nice to write:
[ PSEUDO_CODE ]
TypeInstRef A, B, C; // Actual types might be long, int, int.
A = B * C;
[ / PSEUDO_CODE ]

Thanks for any suggestions you can offer.
Feb 11 '08 #4

Post your reply

Sign in to post your reply or Sign up for a free account.