473,809 Members | 2,787 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Writing a function that changes an unknown-type numeric variable

In my software, there are some variables that represents some settings.
They usually are numerical variables: unsigned char (0..255),
signed char (-127..128), unsigned int (0..65535), signed int (-32767..32768).

I want to write a generic C function that changes the value of one parameter.
For example, a function that takes a pointer to the variable and increments
it by one. Of course, the function doesn't know the variable type (unsigned
char, signed char, and so on).

I thought to solve this problem in two ways, but I don't like them.

The first solution is to create a struct with 4 different pointers where
only one of that is not NULL.

struct {
unsigned char *p_uchar;
signed char *p_schar;
unsigned int *p_uint;
signed int *p_sint;
...
} param;

But I will lost many RAM space and the incrementing function will be poor
optimized.

if( p_uchar )
*p_uchar++;
else if( p_schar )
*p_schar++;
else if( p_uint )
*p_uint++;
else if( p_sint )
*p_sint++;
The other solution is to use a member of the struct to identify the type of
the variable and using void pointer for the variable.

#define PARAMTYPE_UCHAR 1
#define PARAMTYPE_SCHAR 2
#define PARAMTYPE_UINT 3
#define PARAMTYPE_SINT 4
struct {
int type;
void *p_value;
...
};

In this way I will allocate less space than before but the incrementing function
is low optimized.

if( type==PARAMTYPE _UCHAR )
(*(unsigned char *)p_value)++;
else if( type==PARAMTYPE _SCHAR )
(*(signed char *)p_value)++;
....
I wonder that a different and more elegant solution there is.
I think to the printf() function. I pass int and char with %d parameter
and the printf() works well, but it doesn't know the exact type of
the variable.
Maybe the only problem is with unsigned numerical variables that want
the %u parameter, I think.
Jul 19 '06 #1
8 1841
In article <GU************ ********@twiste r1.libero.it>,
pozz <pN************ @libero.itwrote :
>I want to write a generic C function that changes the value of one parameter.
For example, a function that takes a pointer to the variable and increments
it by one. Of course, the function doesn't know the variable type (unsigned
char, signed char, and so on).
>In this way I will allocate less space than before but the incrementing function
is low optimized.
>if( type==PARAMTYPE _UCHAR )
(*(unsigned char *)p_value)++;
else if( type==PARAMTYPE _SCHAR )
(*(signed char *)p_value)++;
...
Try a switch() statement: at worst it will expand in to a chain of
if/else, and the optimizer might be able to do much better than that.

Alternately, try something like,

void increment_uchar ( void *p_value ) { *(unsigned char *)p_value)++ };
void increment_schar ( void *p_value ) { *(signed char *)p_value)++ };
[...]

Then you have a table of increment functions, and use

increment_funct ions[type](p_value);
--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers
Jul 19 '06 #2
pozz <pN************ @libero.itwrite s:
if( p_uchar )
*p_uchar++;
You mean (*p_uchar)++;

[...]
The other solution is to use a member of the struct to identify the type of
the variable and using void pointer for the variable.

#define PARAMTYPE_UCHAR 1
#define PARAMTYPE_SCHAR 2
#define PARAMTYPE_UINT 3
#define PARAMTYPE_SINT 4
struct {
int type;
void *p_value;
...
};
struct tag {
int type;
union {
unsigned char *uc;
signed char *sc;
unsigned int *ui;
signed int *si;
} p;
};

switch (v->type) {
case PARAMTYPE_UCHAR :
(*v->p.uc)++;
break;
case PARAMTYPE_SCHAR :
(*v->p.sc)++;
break;
case PARAMTYPE_UINT:
(*v->p.ui)++;
break;
case PARAMTYPE_SINT:
(*v->p.si)++;
break;
}

Actually, do you really need pointers? If not, you can do this:

struct tag {
int type;
union {
unsigned char uc;
signed char sc;
unsigned int ui;
signed int si;
} p;
};

switch (v->type) {
case PARAMTYPE_UCHAR :
v->p.uc++;
break;
case PARAMTYPE_SCHAR :
v->p.sc++;
break;
case PARAMTYPE_UINT:
v->p.ui++;
break;
case PARAMTYPE_SINT:
v->p.si++;
break;
}

--
int main(void){char p[]="ABCDEFGHIJKLM NOPQRSTUVWXYZab cdefghijklmnopq rstuvwxyz.\
\n",*q="kl BIcNBFr.NKEzjwC IxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+= strchr(p,*q++)-p;if(i>=(int)si zeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Jul 19 '06 #3
Ben Pfaff ha scritto:
struct tag {
int type;
union {
unsigned char *uc;
signed char *sc;
unsigned int *ui;
signed int *si;
} p;
};
I don't want to use union because I must use const variables that are
stored in a FLASH memory (microcontrolle r architecture) and not in RAM
that is small. I must initialize that const variables but I have an old
compiler and I can't initialize the members of a union (only C99 can do
that, I think).

Anyway, your example is very similar to the following:

struct {
int type;
void *p_value;
} p;

Or not?
Jul 19 '06 #4
pozz <pN************ @libero.itwrite s:
Ben Pfaff ha scritto:
>struct tag {
int type;
union {
unsigned char *uc;
signed char *sc;
unsigned int *ui;
signed int *si;
} p;
};

I don't want to use union because I must use const variables that are
stored in a FLASH memory (microcontrolle r architecture) and not in RAM
that is small. I must initialize that const variables but I have an old
compiler and I can't initialize the members of a union (only C99 can do
that, I think).
Hmm. Well, that's rough, I guess.
Anyway, your example is very similar to the following:

struct {
int type;
void *p_value;
} p;
It avoids the need for casts or wordy implicit conversions, but
the effect is similar.
--
Bite me! said C.
Jul 19 '06 #5

pozz wrote:
In my software, there are some variables that represents some settings.
They usually are numerical variables: unsigned char (0..255),
signed char (-127..128), unsigned int (0..65535), signed int (-32767..32768).

I want to write a generic C function that changes the value of one parameter.
For example, a function that takes a pointer to the variable and increments
it by one. Of course, the function doesn't know the variable type (unsigned
char, signed char, and so on).
You can make use of some somewhat fancy macros to do the right thing.
That way there's no long chain of tests at run-time.
Something very close to:

#define DefVar(Name,Typ e ) typedef Type Name##_Type; Name##_Type
Name;

#define Increment( Name ) (( Name##_Type * ) (&Name) ) ++

Jul 19 '06 #6


Ancient_Hacker wrote On 07/19/06 14:39,:
pozz wrote:
>>In my software, there are some variables that represents some settings.
They usually are numerical variables: unsigned char (0..255),
signed char (-127..128), unsigned int (0..65535), signed int (-32767..32768).

I want to write a generic C function that changes the value of one parameter.
For example, a function that takes a pointer to the variable and increments
it by one. Of course, the function doesn't know the variable type (unsigned
char, signed char, and so on).


You can make use of some somewhat fancy macros to do the right thing.
That way there's no long chain of tests at run-time.
Something very close to:

#define DefVar(Name,Typ e ) typedef Type Name##_Type; Name##_Type
Name;

#define Increment( Name ) (( Name##_Type * ) (&Name) ) ++
If I understand your intent, this would be used as

DefVar(fred,int )
DefVar(ethel,sh ort)
...
Increment(fred) ;
Increment(ethel );

expanding to

typedef int fred_Type;
fred_Type fred;
typedef short ethel_Type;
ethel_Type ethel;
...
((fred_Type *)(&fred))++;
((ethel_Type *)(&ethel))++;

Have I got it? If so, I don't see how this improves on

int fred;
short ethel;
...
fred++;
ethel++;

(In fact, it has the appearance of a disimprovement. ) Would
you mind explaining the benefits, or explaining what I've
overlooked?

--
Er*********@sun .com

Jul 19 '06 #7
(In fact, it has the appearance of a disimprovement. ) Would
you mind explaining the benefits, or explaining what I've
overlooked?

The original poster wanted a "function" to increment an arbitrary
variable. My humble macro does that, with considerably less run-time
overhead. Whopee.

Although now looking back, it may be that he just has a void * pointer
coming in, in which case this macro is not quite the ticket.

Since the exact original intent isnt clear the best solution is still
up in the air.

Yet another way: If you can segregate the variables by size, then you
can key off the address:

if( Ptr_To_Var >= &Chr_Base && Ptr_To_Var < &Int_Base ) ((uchar *)
Ptr_To_Var) ++
else
if( Ptr_To_Var >= &Int_Base && Ptr_To_Var < &Long_Base ) ((int *)
Ptr_To_Var) ++
else
if( Ptr_To_Var >= &Long_Base && Ptr_To_Var < &End_Vars ) ((long int *)
Ptr_To_Var)
else { // impossible address }

Jul 19 '06 #8
On Wed, 19 Jul 2006 17:23:50 GMT, pozz <pN************ @libero.it>
wrote in comp.lang.c:
In my software, there are some variables that represents some settings.
They usually are numerical variables: unsigned char (0..255),
signed char (-127..128), unsigned int (0..65535), signed int (-32767..32768).

I want to write a generic C function that changes the value of one parameter.
For example, a function that takes a pointer to the variable and increments
it by one. Of course, the function doesn't know the variable type (unsigned
char, signed char, and so on).

I thought to solve this problem in two ways, but I don't like them.

The first solution is to create a struct with 4 different pointers where
only one of that is not NULL.

struct {
unsigned char *p_uchar;
signed char *p_schar;
unsigned int *p_uint;
signed int *p_sint;
...
} param;

But I will lost many RAM space and the incrementing function will be poor
optimized.

if( p_uchar )
*p_uchar++;
else if( p_schar )
*p_schar++;
else if( p_uint )
*p_uint++;
else if( p_sint )
*p_sint++;
The other solution is to use a member of the struct to identify the type of
the variable and using void pointer for the variable.

#define PARAMTYPE_UCHAR 1
#define PARAMTYPE_SCHAR 2
#define PARAMTYPE_UINT 3
#define PARAMTYPE_SINT 4
struct {
int type;
void *p_value;
...
};

In this way I will allocate less space than before but the incrementing function
is low optimized.

if( type==PARAMTYPE _UCHAR )
(*(unsigned char *)p_value)++;
else if( type==PARAMTYPE _SCHAR )
(*(signed char *)p_value)++;
...
I wonder that a different and more elegant solution there is.
I think to the printf() function. I pass int and char with %d parameter
and the printf() works well, but it doesn't know the exact type of
the variable.
Maybe the only problem is with unsigned numerical variables that want
the %u parameter, I think.
The real question is WHY you want to do this. I see from a later post
that you are talking about "const" objects in an embedded system, but
you can't reliably change const objects.

You should explain the real problem that you are trying to solve, and
not just ask for help with what appears to be a rather clumsy solution
you are trying to kludge. There is probably a much better approach to
do what you really need to accomplish.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 20 '06 #9

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

Similar topics

48
8519
by: Joseph | last post by:
Hi I'm writing a commercial program which must be reliable. It has to do some basic reading and writing to and from files on the hard disk, and also to a floppy. I have foreseen a potential problem. The program may crash unexpectedly while writing to the file. If so, my program should detect this during startup, and then (during startup) probably delete the data added to the file and redo the writing operation.
8
1439
by: Matt Kruse | last post by:
I've found that under some circumstances, some code that I've been using to find an object's coordinates with respect to the viewport does not behave correctly. Is there a function that has been extensively tested under lots of different page conditions that will return the x,y position of an object? Things to consider: 1. Full browser support, as much as possible (meaning, works in any browser where it's possible, not just the latest...
0
2259
by: bohuge | last post by:
Hey! At the time being I'm working on a backup solution for a Qtek9090 pocketpc, which should be able to find and backup outlook data to a server, local files, messages and contact from the sim card (and backup them to a server as well) all written in C#. So I'm making a wrapper for the sim manager api. In order to use it's functions in my device application, I've used platform invoke method, to acces the simmanager functions from...
9
2987
by: Christian Christmann | last post by:
Hi, I was just going through this exercise http://www.cas.mcmaster.ca/~franek/books/membook-answers/ch4/answers-ch4-3.html and I'am confused about the answer. It says: "... the compiler actually does not "know" the signature of malloc(), hence it assumes by default, that it returns int..." How can the function call of 'malloc' work at all if it is unknown?
2
7705
by: news | last post by:
I just upgraded to PHP 4.4.2 on my Slackware 10.2 system. And Apache/mySQL/PHP all work great through a browser. No errors. But when I try to run a PHP script through the command line, which I need to do, I get blocks of errors like: root@slackserve:/var/www/htdocs# php ./phptest.php PHP Warning: Unknown(): Unable to load dynamic library '/usr/lib/php/extensions/mysql.so' - libmysqlclient.so.14: cannot open shared object file: No such...
2
1910
by: Qingning Huo | last post by:
Hi, Is this valid C++? It compiles on VC8 and g++ 4.1.1, but fails on Sun CC 5.8. --cut -- template<class T> class TClass { public:
6
11594
by: Jack White | last post by:
Does anyone know if an analogue to the "swap()" function found in C++ exists in C#. For those not familiar, let's say you have a function that loads some collection passed in by reference. If an error occurs while loading then the collection will be in an indeterminate state. The work-around in C++ is to load a temporary collection first and once successful, invoke a (native) "swap()" function to exchange each object's internal "handle" to...
5
1430
by: rotems | last post by:
Hi, I have a problem. I need to open unknown number of files for writing. In order to solve the problem I tried to open files in an array, where each node in the array is a pointer to a file. I succeed in opening the files and close all the files, but I can't write to them.
4
1830
by: lostlander | last post by:
In ARMCC, and Microsoft C, when i use a function which is never defined or delared, it gives out a warning, not a compiling error? why? (This leads to a bug to my program since I seldom pay much attention to warnings...) Thanks for explanation!
0
9721
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9601
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10637
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10379
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
7660
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6881
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5550
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3861
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3014
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.