473,395 Members | 1,870 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,395 software developers and data experts.

void* operations

Hi,
I haven't done a lot of C++ programming (done a lot of it in C) and the
reason why I'm considering switching now is also the question I'm
posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return an
enum which contains information about the data type of this data. So
what I've done in the past is made a switch case statement based on the
data type enum and then explicitly re-cast the void* to the appropriate
data type.

Now I have a case where I have two values and each of them could be any
data type. Lets say I have to multiply them. So if I was to use my
usual method I'd have a switch case statement with numDataType(C)2
(combination) cases. Does C++ have a better way of extracting data from
void*?

Thanks for your help,
Ashish.

Feb 17 '06 #1
21 2276
as***************@gmail.com wrote:
I haven't done a lot of C++ programming (done a lot of it in C) and
the reason why I'm considering switching now is also the question I'm
posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return an
enum which contains information about the data type of this data. So
what I've done in the past is made a switch case statement based on
the data type enum and then explicitly re-cast the void* to the
appropriate data type.

Now I have a case where I have two values and each of them could be
any data type. Lets say I have to multiply them. So if I was to use my
usual method I'd have a switch case statement with numDataType(C)2
(combination) cases. Does C++ have a better way of extracting data
from void*?


"Better" in what sense?

V
--
Please remove capital As from my address when replying by mail
Feb 18 '06 #2
as***************@gmail.com wrote:
Hi,
I haven't done a lot of C++ programming (done a lot of it in C) and the
reason why I'm considering switching now is also the question I'm
posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return an
enum which contains information about the data type of this data. So
what I've done in the past is made a switch case statement based on the
data type enum and then explicitly re-cast the void* to the appropriate
data type.

Now I have a case where I have two values and each of them could be any
data type. Lets say I have to multiply them. So if I was to use my
usual method I'd have a switch case statement with numDataType(C)2
(combination) cases. Does C++ have a better way of extracting data from
void*?

Yes, don't!

Return a pointer to a base type and derive all your data classes from
it. A case of refactoring from switch to polymorphism.

class Base
{
virtual ~base() {}
...
};

class Data1 : public Base
{
....
};

....

--
Ian Collins.
Feb 18 '06 #3

Victor Bazarov wrote:
as***************@gmail.com wrote:
I haven't done a lot of C++ programming (done a lot of it in C) and
the reason why I'm considering switching now is also the question I'm
posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return an
enum which contains information about the data type of this data. So
what I've done in the past is made a switch case statement based on
the data type enum and then explicitly re-cast the void* to the
appropriate data type.

Now I have a case where I have two values and each of them could be
any data type. Lets say I have to multiply them. So if I was to use my
usual method I'd have a switch case statement with numDataType(C)2
(combination) cases. Does C++ have a better way of extracting data
from void*?


"Better" in what sense?

V
--
Please remove capital As from my address when replying by mail


Victor, "better way" in the sense that will it be possible for me to
define some sort of template or something else that will alow me to
have a common function that can be called with a void* irrespective of
the data type of the data that the pointer actually points to.

Ashish.

Feb 18 '06 #4

Ian Collins wrote:
as***************@gmail.com wrote:
Hi,
I haven't done a lot of C++ programming (done a lot of it in C) and the
reason why I'm considering switching now is also the question I'm
posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return an
enum which contains information about the data type of this data. So
what I've done in the past is made a switch case statement based on the
data type enum and then explicitly re-cast the void* to the appropriate
data type.

Now I have a case where I have two values and each of them could be any
data type. Lets say I have to multiply them. So if I was to use my
usual method I'd have a switch case statement with numDataType(C)2
(combination) cases. Does C++ have a better way of extracting data from
void*?

Yes, don't!

Return a pointer to a base type and derive all your data classes from
it. A case of refactoring from switch to polymorphism.

class Base
{
virtual ~base() {}
...
};

class Data1 : public Base
{
...
};

...

--
Ian Collins.


I'm sorry Ian but I have no idea what you just said, as I mentioned
before I don't have much C++ knowledge. Could you please elaborate a
little more? And maybe suggest some of the things I should be reading
up to do this; virtual seems to be something I should learn more about.

Thanks,
Ashish

Feb 18 '06 #5
Praetorian wrote:
[redacted]

I'm sorry Ian but I have no idea what you just said, as I mentioned
before I don't have much C++ knowledge. Could you please elaborate a
little more? And maybe suggest some of the things I should be reading
up to do this; virtual seems to be something I should learn more about.

The canonical example is a drawing program with shapes.

class Shape {
public:
virtual void Draw();
// other methods redacted
};

class Circle : public Shape {
public:
void Draw();
// other methods redacted
};

class Rectangle : public Shape {
public:
void Draw();
// other methods redacted
};

Now, you can just keep track of Shape*'s. Since you're not familiar
with C++, I'll use an array (yes, C++ people, I know he should use a
vector, and yes, I know there's likely memory leaks in the sample).

Shape* shapes[NSHAPES];

// reads shapes from a file.
int ReadShapes(Shape* shapelist[], int max_shapes);

int main()
{
int n = ReadShapes(shapes, NSHAPES);

for (int i = 0; i < n ; ++i)
shapes[i]->Draw();
}

In this example, you don't have to worry about what kind of shape each
element of the array "shapes" is. Each element "knows" what kind of
data it is and does the right thing when asked to draw itself.

That's a very simplified example of polymorphism. Shape is the base
class, and Circle and Rectangle are derived classes. That's what Ian
was talking about. Instead of returning void* and having a switch
statement from hell, you create a class hierarchy with virtual
functions, return a pointer (or a reference) to the base class, and call
the virtual function, which "knows what to do".

I highly recommend getting "Accelerated C++" by Koenig and Moo.

Feb 18 '06 #6
> I'm sorry Ian but I have no idea what you just said, as I mentioned
before I don't have much C++ knowledge. Could you please elaborate a
little more? And maybe suggest some of the things I should be reading
up to do this; virtual seems to be something I should learn more about.

Thanks,
Ashish


Let's say you have a bunch of methods of transportation represented as
types (e.g. bus, taxi, train, car, tram, etc) and despite all the
differences in between, all of them can be started and stopped.

What C++ allows you to do, is to start and/or stop any type of
transportation without knowing which type it is. What you do is you put
functions start and stop in a base class and derive all other
transportation from that class:

class transport
{
public:
virtual void start(void) = 0;
virtual void stop (void) = 0;

virtual ~transport(); // destructor
};

class bus: public transport
{
public:
void start(void)
{
signal_passengers();
close_the_doors();
log_timetable();
ignite_engine();
// ...
}

void stop(void)
{
apply_brake();
open_the_doors();
wait_for_passengers_to_get_off();
log_time_table();
switch_off_engine();
}

// also a bunch of bus-specific features...
};

class taxi: public transport
{
public:
void start(void)
{
start_mile_counter();
say_hello_to_passenger();
ask_for_destination();
off_you_go();
}

void stop(void)
{
apply_brake();
get_paid();
say_goodbye();
}

// also a bunc of taxi-specific features...
};

Now a bus* pointer is also a transport* pointer; a taxi* is also a
transport*; etc. So you can do someting like:

int main()
{
transport* t;
taxi my_favorite;
bux my_second_favorite;

t = &my_favorite;
t->start(); // starts a taxi
t->stop(); // stops a taxi

t = &my_second_favorite;
t->start(); // starts a bus
t->stop(); // stops a bus
}

Well, if you have no clue what I am talking about I strongly recommend
you to grab a C++ book and read on classes and derived classes.

Regards,
Ben
Feb 18 '06 #7
Praetorian wrote:

I'm sorry Ian but I have no idea what you just said, as I mentioned
before I don't have much C++ knowledge. Could you please elaborate a
little more? And maybe suggest some of the things I should be reading
up to do this; virtual seems to be something I should learn more about.

Oh dear, you should get yourself a couple of decent C++ books,
"Accelerated C++" and "The C++ programming language, 3rd edition" are a
good start.

A very common way to replace C style switches is to use polymorphic
types and virtual methods. You must understand these concepts, a simple
google for "polymorphic virtual C++" should get you started.

Welcome to the fun world of C++.

--
Ian Collins.
Feb 18 '06 #8
Praetorian wrote:
Victor Bazarov wrote:
as***************@gmail.com wrote:
I haven't done a lot of C++ programming (done a lot of it in C) and
the reason why I'm considering switching now is also the question
I'm posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return
an enum which contains information about the data type of this
data. So what I've done in the past is made a switch case statement
based on the data type enum and then explicitly re-cast the void*
to the appropriate data type.

Now I have a case where I have two values and each of them could be
any data type. Lets say I have to multiply them. So if I was to use
my usual method I'd have a switch case statement with
numDataType(C)2 (combination) cases. Does C++ have a better way of
extracting data from void*?


"Better" in what sense?

V
--
Please remove capital As from my address when replying by mail


Victor, "better way" in the sense that will it be possible for me to
define some sort of template or something else that will alow me to
have a common function that can be called with a void* irrespective of
the data type of the data that the pointer actually points to.


Apparently, your 'void*' only designates the address of some memory
area. If the object that occupies that memory has been successfully
constructed by those "library functions", then you can simply _cast_
the pointer to the pointer to the type as indicated by that enum.
You can use 'static_cast'.

If your memory area does _not_ contain a successfully constructed object,
then the cast doesn't help. However, you probably know the layout of
the memory, so you can easily write the algorithm of "recreating" the
objects. I strongly recommend letting the objects construct themselves
by having properly defined _explicit_ constructors to which you will
pass the void*.

Having re-read your post, I am still unable to understand what it is
you do not like about "recasting" as you put it. If you're stuck with
those library functions, there is no simpler or more straightforward
way.

V
--
Please remove capital As from my address when replying by mail
Feb 18 '06 #9

Victor Bazarov wrote:
Praetorian wrote:
Victor Bazarov wrote:
as***************@gmail.com wrote:
I haven't done a lot of C++ programming (done a lot of it in C) and
the reason why I'm considering switching now is also the question
I'm posting here.

I have some library functions that return to me a void* to data that
has been specifed by the user. There are also functions that return
an enum which contains information about the data type of this
data. So what I've done in the past is made a switch case statement
based on the data type enum and then explicitly re-cast the void*
to the appropriate data type.

Now I have a case where I have two values and each of them could be
any data type. Lets say I have to multiply them. So if I was to use
my usual method I'd have a switch case statement with
numDataType(C)2 (combination) cases. Does C++ have a better way of
extracting data from void*?

"Better" in what sense?

V
--
Please remove capital As from my address when replying by mail


Victor, "better way" in the sense that will it be possible for me to
define some sort of template or something else that will alow me to
have a common function that can be called with a void* irrespective of
the data type of the data that the pointer actually points to.


Apparently, your 'void*' only designates the address of some memory
area. If the object that occupies that memory has been successfully
constructed by those "library functions", then you can simply _cast_
the pointer to the pointer to the type as indicated by that enum.
You can use 'static_cast'.

If your memory area does _not_ contain a successfully constructed object,
then the cast doesn't help. However, you probably know the layout of
the memory, so you can easily write the algorithm of "recreating" the
objects. I strongly recommend letting the objects construct themselves
by having properly defined _explicit_ constructors to which you will
pass the void*.

Having re-read your post, I am still unable to understand what it is
you do not like about "recasting" as you put it. If you're stuck with
those library functions, there is no simpler or more straightforward
way.

V
--
Please remove capital As from my address when replying by mail


Thank you for all of your replies; and I have been busy Google searches
for C++ tutorials since my last post; in fact I was just about to read
about virtual functions when I decided to check this posting again.

Victor, the void* returned to me does point to a successfully
constructed object in memory, having the size of whatever the data type
enum; I can simply re-cast to the data type pointer and access it
without worrying about any kind of memory corruption (thank God for
that). Let me try and illustrate my problem with explicit casting using
an example:

Let's say I have 2 values that I need to multiply and each value may be
an int16 or an int32. I have void pointers v1 and v2 to each. So the
way I see what I need to do is something like:

if(d1 == INT16 && d2 == INT16)
{
v1int16 = (int16 *)v1;
v2int16 = (int16 *)v2;
output = v1*v2;
}
else if(d1 == INT16 && d2 == INT32)
{
v1int16 = (int16 *)v1;
v2int32 = (int32 *)v2;
output = v1*v2;
}
else if(d1 == INT32 && d2 == INT16)
{ .....}
else
{......}

Now this becomes rather tedious because I need to support 10 different
data types and I have to operate on 3 values instead of 2; basically a
switch case or if else construct from hell as someone put it in an
earlier post.

Although the virtual function method looks promising doesn't that still
mean I need to have a function for each combination of data types? I
was looking into templates but even with them the problem is that my
knowledge of the data type lies in an enum value and I don't know how
to incorporate this in a template; maybe a template which does the
final operation on pointers and virtual functions to 'condition' the
values based on their data types, if any conditioning is needed. These
functions would return pointers that can be used by the template.

I'm just throwing out ideas here and forgive me if I've managed to
sound stupid with my solution. You guys should be able to suggest
something that works for me.

Thanks,
Ashish.

Feb 18 '06 #10
Praetorian wrote:
[..]
Victor, the void* returned to me does point to a successfully
constructed object in memory, having the size of whatever the data
type enum; I can simply re-cast to the data type pointer and access it
without worrying about any kind of memory corruption (thank God for
that). Let me try and illustrate my problem with explicit casting
using an example:

Let's say I have 2 values that I need to multiply and each value may
be an int16 or an int32. I have void pointers v1 and v2 to each. So
the way I see what I need to do is something like:

if(d1 == INT16 && d2 == INT16)
{
v1int16 = (int16 *)v1;
v2int16 = (int16 *)v2;
You probably meant

v1int16 = *(int16*)v1;

and so on...
output = v1*v2;
What type is 'output'?
}
else if(d1 == INT16 && d2 == INT32)
{
v1int16 = (int16 *)v1;
v2int32 = (int32 *)v2;
output = v1*v2;
}
else if(d1 == INT32 && d2 == INT16)
{ .....}
else
{......}

Now this becomes rather tedious because I need to support 10 different
data types and I have to operate on 3 values instead of 2; basically a
switch case or if else construct from hell as someone put it in an
earlier post.

Although the virtual function method looks promising doesn't that
still mean I need to have a function for each combination of data
types?
You bet.
I was looking into templates but even with them the problem is
that my knowledge of the data type lies in an enum value and I don't
know how to incorporate this in a template; maybe a template which
does the final operation on pointers and virtual functions to
'condition' the values based on their data types, if any conditioning
is needed. These functions would return pointers that can be used by
the template.
Templates are not going to help you since your types are not known
until run-time. Still, even then they are not true C++ types in the
run-time sense (polymorphic types). They are just chunks of memory
whose meaning is expressed in some other values. Even though they
have been constructed, to use them you need to provide some switch
statement, there is no escaping that.

Now, you _could_ define your base class for your operations and then
derive your 10 types from it. Then all the operations just need to
be implemented as a case of double dispatch (look it up).

An alternative would be to extract those values into another type,
some kind of common denominator. If they are all integrals, use
'long' or 'unsigned long' to represent the values. If that's not
enough, use implementation-specific larger value (like 'int64_t' in
Visual C++, for example).
I'm just throwing out ideas here and forgive me if I've managed to
sound stupid with my solution. You guys should be able to suggest
something that works for me.


Hey, at the end of the day, we're not going to solve your problem.
You have to do it yourself. Bite the bullet and just code all those
1000 possibilities.

V
--
Please remove capital As from my address when replying by mail
Feb 18 '06 #11

Victor Bazarov wrote:
Praetorian wrote:
[..]
Victor, the void* returned to me does point to a successfully
constructed object in memory, having the size of whatever the data
type enum; I can simply re-cast to the data type pointer and access it
without worrying about any kind of memory corruption (thank God for
that). Let me try and illustrate my problem with explicit casting
using an example:

Let's say I have 2 values that I need to multiply and each value may
be an int16 or an int32. I have void pointers v1 and v2 to each. So
the way I see what I need to do is something like:

if(d1 == INT16 && d2 == INT16)
{
v1int16 = (int16 *)v1;
v2int16 = (int16 *)v2;


You probably meant

v1int16 = *(int16*)v1;

and so on...
output = v1*v2;


What type is 'output'?
}
else if(d1 == INT16 && d2 == INT32)
{
v1int16 = (int16 *)v1;
v2int32 = (int32 *)v2;
output = v1*v2;
}
else if(d1 == INT32 && d2 == INT16)
{ .....}
else
{......}

Now this becomes rather tedious because I need to support 10 different
data types and I have to operate on 3 values instead of 2; basically a
switch case or if else construct from hell as someone put it in an
earlier post.

Although the virtual function method looks promising doesn't that
still mean I need to have a function for each combination of data
types?


You bet.
I was looking into templates but even with them the problem is
that my knowledge of the data type lies in an enum value and I don't
know how to incorporate this in a template; maybe a template which
does the final operation on pointers and virtual functions to
'condition' the values based on their data types, if any conditioning
is needed. These functions would return pointers that can be used by
the template.


Templates are not going to help you since your types are not known
until run-time. Still, even then they are not true C++ types in the
run-time sense (polymorphic types). They are just chunks of memory
whose meaning is expressed in some other values. Even though they
have been constructed, to use them you need to provide some switch
statement, there is no escaping that.

Now, you _could_ define your base class for your operations and then
derive your 10 types from it. Then all the operations just need to
be implemented as a case of double dispatch (look it up).

An alternative would be to extract those values into another type,
some kind of common denominator. If they are all integrals, use
'long' or 'unsigned long' to represent the values. If that's not
enough, use implementation-specific larger value (like 'int64_t' in
Visual C++, for example).
I'm just throwing out ideas here and forgive me if I've managed to
sound stupid with my solution. You guys should be able to suggest
something that works for me.


Hey, at the end of the day, we're not going to solve your problem.
You have to do it yourself. Bite the bullet and just code all those
1000 possibilities.

V
--
Please remove capital As from my address when replying by mail


Victor, sorry about the typos earlier but you interpreted them
correctly. Output data type is my third variable data type. I'm using
this in a block that will be used in Simulink simulations and all 3
data types will be specified by the user on the block dialog. The
functions that return the void* to me are Simulink callback methods
which are called at every time step to calculate the output of the
block. Simulink doesn't support 64-bit data types and anyway, I don't
want to go down that path because I do actually want to do what the
user is asking me to do. For instance if the user gives me data sets
which will result in an overflow I want there to be an overflow; which
may be hard to reproduce if I up-cast the data.

I just read the definition of double dispatch and it says that it is
used in cases where data types of arguments are only know at run time;
sounds like it is exactly what I need. But I should first look into
some of the more basic aspects of C++ like polymorphism and inheritance
before I jump into that. In the meanwhile could you tell me if you
think it's possible to solve my problem using double dispatch. Because
if not and I'm going to have to code 1000 switch case statements then
I'm going back to C :-)

Feb 18 '06 #12
Praetorian wrote:
[...]
I just read the definition of double dispatch and it says that it is
used in cases where data types of arguments are only know at run time;
sounds like it is exactly what I need. But I should first look into
some of the more basic aspects of C++ like polymorphism and
inheritance before I jump into that. In the meanwhile could you tell
me if you think it's possible to solve my problem using double
dispatch. Because if not and I'm going to have to code 1000 switch
case statements then I'm going back to C :-)


Look, if I were to give any weight to my answer about the possibility
to solve your problem with double dispatch, I'd have to basically solve
it an I have neither the time, nor the energy. And you're right, it
would require you to learn inheritance and polymorphism.

As to going back to C, good luck, but I think you'd still need to write
your 1000 switch case statements there just as well.

V
--
Please remove capital As from my address when replying by mail
Feb 18 '06 #13
What will this code be used for? Please don't say: "to multiply scalars
of different type together", something more higher level information
about the intended use would come in handy when factoring an useful
answer.. :)

Feb 19 '06 #14

persenaama wrote:
What will this code be used for? Please don't say: "to multiply scalars
of different type together", something more higher level information
about the intended use would come in handy when factoring an useful
answer.. :)


In this case it is something as mundane as multiplying 2-3 numbers
together after converting them to the data types that the user has
specified.

Feb 19 '06 #15
Whatever. If you have 10 scalar types, say,

u8, s8, u16, s16, u32, s32, u64, s64, f32, f64

(u = unsigned integer, # bits )
(s = signed integer, # bits)
(f = floating point, # bits)

This gives us 100 permutations with numDownConversion *
numUpConversion, this is unacceptable. There is a workaround, some
background information.

f32 can store all values of u8, u16, u32. Also s8, s16 and same applies
for signed. f64 respectively, when available on your platoform
(sizeof(double) == 8 and there are 8 bits to a char) all integer values
can be presented.

So, to evaluate your expression up-convert to f64, do yer thang, and
down-convert to type you want. Remember the result might not fit but
same problem persists even if you do the computation in integer.

This, ofcourse, assumes that you are willing to accept that this isn't
a c++ program that you can assume to work everywhere. It is a c++
program that will work on a LOT of platforms, though.

Or you can use Perl.

Feb 20 '06 #16
persenaama wrote:
[...]
f32 can store all values of u8, u16, u32.
No, it cannot. Count significant bits in f32's mantissa.
[...]


V
--
Please remove capital As from my address when replying by mail
Feb 20 '06 #17

persenaama wrote:
Whatever. If you have 10 scalar types, say,

u8, s8, u16, s16, u32, s32, u64, s64, f32, f64

(u = unsigned integer, # bits )
(s = signed integer, # bits)
(f = floating point, # bits)

This gives us 100 permutations with numDownConversion *
numUpConversion, this is unacceptable. There is a workaround, some
background information.

f32 can store all values of u8, u16, u32. Also s8, s16 and same applies
for signed. f64 respectively, when available on your platoform
(sizeof(double) == 8 and there are 8 bits to a char) all integer values
can be presented.

So, to evaluate your expression up-convert to f64, do yer thang, and
down-convert to type you want. Remember the result might not fit but
same problem persists even if you do the computation in integer.

This, ofcourse, assumes that you are willing to accept that this isn't
a c++ program that you can assume to work everywhere. It is a c++
program that will work on a LOT of platforms, though.

Or you can use Perl.


Unfortunately, it's not as simple as that. I don't have any data type
over 32 bits, both singles and doubles are 32 bits on my target
platform (DSP). So I can't just put everything into 64-bit integers.
And I can't use anything other than C or C++ to code this.

Ashish.

Feb 20 '06 #18
My bad, ofcourse, you are correct. The advice was to use f64, the
prognosis was flawed. I did ponder how to reply such sparsely worded
question with very broad implications, and came to conclusion that Perl
or other similiar scripting language is what he wants to use. That
answer would have been fuck-you-in-the-face therefore posted the most
trivial ad-hoc answer possible, because the most obvious answer of "do
all permutations" is a chore.

He did not state in any way or form how broad context he has in mind,
"mundane" gives implication that shortcuts are alternative. If it
weren't mundane, I would recommend writing a good expression evaluation
engine. Or using pre-written one, if his emploers (assuming he is
employed and doing this as part of his work, again could be wrong)
licensing policies allow.

How complex system he wants to develop for this task depends on how
important tha task is: how much it can cost to develop. If it's just
multiply two numbers I doubt he has too much time allocated for that in
the project schedule. I could be wrong. The simplest solution is to up
convert (to double for up to uint32) and forget it after it's done and
tested. uint64 won't even fit into long double (assuming it's 80 bits
as-in x86).

If that won't work for his platform (apparently doesn't) what he should
do next depends on definition of his problem. If his values are limited
to integer, of some precise range of integers, of if 16 bit is largest
integer, or 32 bit is the largest integer his input is, he might do w/o
large number library (or code that does the same). Etc.. too broad
context to give a clear-cut answer. I don't write code before knowing
what it's for, what it is supposed to do. I made a mistake of answering
poorly defined problem.

Feb 21 '06 #19
Come again? Is the problem that the result does not fit into types you
have, or that the input types are not static? Both?

What you have so far? Why you think it does not work?

Can you afford to implement multiply yourself, would that be too slow?
You didn't mention you are in performance critical section of
application, so that might do the trick. If you can afford that, it's
very easy, shouldn't take you more than 15 minutes or so.

Feb 21 '06 #20
Here's a brute-force peasant algorithm implementation:

uint32 mul(uint32 a, uint32 b)
{
uint32 v = 0;
for ( ; b; )
{
v += a & (0 - (b & 1));
a <<= 1;
b >>= 1;
}
return v;
}

It multiplies two 32 bit values, if you want 64 bit result you need to
write 64 bit addition and use "uint64" for v. Easiest way to do that is
something like this, since you don't have 64 bit integers:

struct uint64
{
uint32 v[2];
// .. operators you need here..
};

How you going to use the 64 bit result is up to you.. if you want
signed, too, it is fairly trivial.

This is not really answering your question, which is a bit mystry what
the problem is. Choosing the right types for compiler/language built-in
* operator? Or how to store and broadcast the user supplied
non-statically typed values to the built-in * operator?

By now, you should already have the code. I'm 99% sure that you do, so
the thread is closed? ;-o

Feb 21 '06 #21

persenaama wrote:
Here's a brute-force peasant algorithm implementation:

uint32 mul(uint32 a, uint32 b)
{
uint32 v = 0;
for ( ; b; )
{
v += a & (0 - (b & 1));
a <<= 1;
b >>= 1;
}
return v;
}

It multiplies two 32 bit values, if you want 64 bit result you need to
write 64 bit addition and use "uint64" for v. Easiest way to do that is
something like this, since you don't have 64 bit integers:

struct uint64
{
uint32 v[2];
// .. operators you need here..
};

How you going to use the 64 bit result is up to you.. if you want
signed, too, it is fairly trivial.

This is not really answering your question, which is a bit mystry what
the problem is. Choosing the right types for compiler/language built-in
* operator? Or how to store and broadcast the user supplied
non-statically typed values to the built-in * operator?

By now, you should already have the code. I'm 99% sure that you do, so
the thread is closed? ;-o


I'm sorry, I didn't check this thread at all yesterday and that's why I
didn't respond to your posts. I don't have the code yet. Let me explain
the problem to you once more: I have a dialog box on which the user
select data types for 3 variables and an operation to be performed on
those variables. The data types I have are 8, 16 and 32 bit signed and
unsigned integers and floats and doubles; total of 8. That leads to
8*8*8 permutations if I was to code it with switch case or if else
statements. This of course is unacceptable and so what I do for now is
restrict the user to 2 data type options only.

I have some library functions which will return a void * to the 3
variables and I can get their data types from another function which
will return an enum of the data type. It is then my job to type cast
the void * to the appropriate data type. What I would like to have is
some mechanism that lets data types be decided at run time and a
general template like thing (I don't know much C++ so I'm just throwing
out terms I've learned in the past few days) that will let me do the
operation using the appropriate data type.

Someone mentioned double dispatch in this thread and I looked into that
but unfortuantely it is a little too complicated for me to understand
without delving deeper into C++. I've started doing that, bought a
couple of books and reading tutorials online but you guessed correctly
that there isn't much time allocated to this in the project and so I'm
doing this on my own time; so it's slow going. However, once I develop
this i could use it whenever I'm faced with a problem of this kind and
so it would be rather useful to get it working.

Also, this is part of my work, not a school project; so you're not
helping me do my homework :-)

Feb 22 '06 #22

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

Similar topics

5
by: trying_to_learn | last post by:
Hello All Have another qn from the practice exercises. I ve done the exercise and the birds fly member fn was called successfully. But i still cant answer the authors qn. why this ability to...
6
by: dam_fool_2003 | last post by:
Hai, I thank those who helped me to create a single linked list with int type. Now I wanted to try out for a void* type. Below is the code: #include<stdlib.h> #include<stdio.h>...
15
by: Stig Brautaset | last post by:
Hi group, I'm playing with a little generic linked list/stack library, and have a little problem with the interface of the pop() function. If I used a struct like this it would be simple: ...
2
by: Xiangliang Meng | last post by:
Hi, all. As far as I know, the speical arithmetic operator on void pointer is an externsion in GNU CC. However, I could not find the relative topics in C99. Would someone like to help me find...
27
by: Erik de Castro Lopo | last post by:
Hi all, The GNU C compiler allows a void pointer to be incremented and the behaviour is equivalent to incrementing a char pointer. Is this legal C99 or is this a GNU C extention? Thanks in...
14
by: arun | last post by:
Hi, Why sizeof operator when applied on void returns one when compiled with gcc compiler ??. When i tried it on VC++ compiler, it gives an error. But another version of the VC++ compiler on my...
18
by: Giannis Papadopoulos | last post by:
According to the standard (ISO C99 draft WG14/N1124), void is the incomplete type that cannot be completed and comprises the empty set of values. Since it declares the absense of a value can it be...
18
by: hyderabadblues | last post by:
What does (void) poService in followinf peace of code mean tclCtrlBoard::tclCtrlBoard( void* poService ) { # if defined Something (void) poService; \\ What does this mean }
16
by: PeterAPIIT | last post by:
Hello all C++ expert programmer, i have wrote partial general allocator for my container. After reading standard C++ library and code guru article, i have several questions. 1. Why...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
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.