473,395 Members | 1,972 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.

Determining Variable type

I have some C functions (with variable length argument lists) that use
void pointers as arguments.

Is there a way to determine at runtime what type of parameter is
actually passed on to the function? PHP and my oldskool turbopascal
provide a typeof() function, but my C compiler (gcc 3.4.1) does not seem
to provide this function. Perhaps someone crafted a library with some
smart code able to inspect the variable passed to a certain function?

I am aware if such a function exists it may well be platform/compiler
dependent. My primary interest lies with Linux on Intel platforms, C
compilers 3.x or 4.x

Thanks in advance
Sh.
Aug 5 '06 #1
9 2766
In article <44**********************@news.xs4all.nl>,
Schraalhans Keukenmeester <fi********************@xsfourall.ennelwrote:
>I have some C functions (with variable length argument lists) that use
void pointers as arguments.
>Is there a way to determine at runtime what type of parameter is
actually passed on to the function?
No, not in standard C.

>Perhaps someone crafted a library with some
smart code able to inspect the variable passed to a certain function?
I am aware if such a function exists it may well be platform/compiler
dependent. My primary interest lies with Linux on Intel platforms, C
compilers 3.x or 4.x
Well, if you are willing to make it that specific and distinctly
non-portable, then what you do is open the executable as a file, and
grot through the symbol tables in the debugging information, and
if you are lucky the address that has been passed to you is that of
a static variable (or function) that you can match against... possibly
dead-ending there.

But there is, in general, simply no way to do what you are asking
in C, no matter how smart the library. Consider a union: by
definition in C, the addresses of the members all start at the
same memory location and the void* of all of those are the same.
union { int X; float Y } Z -- then (void*) &Z.X is the same
as (void*) &Z.Y (or at least will "compare equal".)

Address equivilence of void* is used routinely in C, as it is
fundamental to the use of malloc().
--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers
Aug 5 '06 #2
Walter Roberson wrote:
In article <44**********************@news.xs4all.nl>,
Schraalhans Keukenmeester <fi********************@xsfourall.ennelwrote:
>I have some C functions (with variable length argument lists) that use
void pointers as arguments.
>Is there a way to determine at runtime what type of parameter is
actually passed on to the function?

No, not in standard C.

>Perhaps someone crafted a library with some
smart code able to inspect the variable passed to a certain function?
I am aware if such a function exists it may well be platform/compiler
dependent. My primary interest lies with Linux on Intel platforms, C
compilers 3.x or 4.x

Well, if you are willing to make it that specific and distinctly
non-portable, then what you do is open the executable as a file, and
grot through the symbol tables in the debugging information, and
if you are lucky the address that has been passed to you is that of
a static variable (or function) that you can match against... possibly
dead-ending there.

But there is, in general, simply no way to do what you are asking
in C, no matter how smart the library. Consider a union: by
definition in C, the addresses of the members all start at the
same memory location and the void* of all of those are the same.
union { int X; float Y } Z -- then (void*) &Z.X is the same
as (void*) &Z.Y (or at least will "compare equal".)

Address equivilence of void* is used routinely in C, as it is
fundamental to the use of malloc().
Thanks for your quick reply Walter, I feared this outcome already. I
don't intend on pushing my luck inspecting executables and 'possibly'
having a usable result.

I read up on variable length argument lists and now see the
impossibility, as well as the rationale behind how (e.g.) printf() works.
Can't have it all. Having void pointers and strongly typed vars to begin
with is a blessing in itself.

Kindest,
Sh.
Aug 5 '06 #3
Schraalhans Keukenmeester (in 44**********************@news.xs4all.nl)
said:

| I have some C functions (with variable length argument lists) that
| use void pointers as arguments.
|
| Is there a way to determine at runtime what type of parameter is
| actually passed on to the function? PHP and my oldskool turbopascal
| provide a typeof() function, but my C compiler (gcc 3.4.1) does not
| seem to provide this function. Perhaps someone crafted a library
| with some smart code able to inspect the variable passed to a
| certain function?
|
| I am aware if such a function exists it may well be
| platform/compiler dependent. My primary interest lies with Linux on
| Intel platforms, C compilers 3.x or 4.x

The easiest way would probably be to make the first parameter the
pointer to a string that describes the remaining parameters - like
printf, only more simple.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Aug 5 '06 #4
Morris Dovey wrote:
Schraalhans Keukenmeester (in 44**********************@news.xs4all.nl)
said:

| I have some C functions (with variable length argument lists) that
| use void pointers as arguments.
|
| Is there a way to determine at runtime what type of parameter is
| actually passed on to the function? PHP and my oldskool turbopascal
| provide a typeof() function, but my C compiler (gcc 3.4.1) does not
| seem to provide this function. Perhaps someone crafted a library
| with some smart code able to inspect the variable passed to a
| certain function?
|
| I am aware if such a function exists it may well be
| platform/compiler dependent. My primary interest lies with Linux on
| Intel platforms, C compilers 3.x or 4.x

The easiest way would probably be to make the first parameter the
pointer to a string that describes the remaining parameters - like
printf, only more simple.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto

I just ran into the following that may be of interest to others, it
surely helps me in some ways...

Link: http://www.ddj.com/dept/cpp/184401956

Summary:
gcc has a (nonstandard C) way of 'knowing' what type of var is used, by
means of the typeof() operator:

int i;
typeof(i) j; //declares a variable j with the same type as i

Not exactly what I was looking for, but still I may be able to put it to
use.

Just thought I'd let you know...
Regards
Sh.

Aug 5 '06 #5
>I just ran into the following that may be of interest to others, it
>surely helps me in some ways...

Link: http://www.ddj.com/dept/cpp/184401956

Summary:
gcc has a (nonstandard C) way of 'knowing' what type of var is used, by
means of the typeof() operator:

int i;
typeof(i) j; //declares a variable j with the same type as i
But if you have a function with a parameter:

int unc(void *p)
{
/* typeof(p) here is *ALWAYS* void * in gcc, regardless of */
/* what argument is passed to unc() */
}
>Not exactly what I was looking for, but still I may be able to put it to
use.
C doesn't have run-time-variable typing, with the exception of
C99 variable-size arrays, and even in that case, the size isn't
passed with the array as a function argument unless you pass it
explicitly.

Aug 6 '06 #6
There's no really good way to do this, as C wasnt intended to ever do
anything in this realm.
Yes, there are the vararg macros, but they're somewhat complex to use
properly.

What I'd do is write a little preprocessor, about a 7-line program in
Perl would do it, one that would take input like this:

int i; float xx; double xx;

callwithlooseargs( i, x, xx, "nice args, eh?" ); /*< i f d s
<>*/

and generate this:

callwithlooseargs_int( i, );
callwithlooseargs_float( x );
callwithlooseargs_double( xx );
callwithlooseargs_string( "nice args, eh?" );

.... then it's up to you to supply those functions.

Aug 6 '06 #7
"Ancient_Hacker" <gr**@comcast.netwrites:
There's no really good way to do this, as C wasnt intended to ever do
anything in this realm.
To do what? Please quote context.
Yes, there are the vararg macros, but they're somewhat complex to use
properly.

What I'd do is write a little preprocessor, about a 7-line program in
Perl would do it, one that would take input like this:

int i; float xx; double xx;

callwithlooseargs( i, x, xx, "nice args, eh?" ); /*< i f d s
<>*/

and generate this:

callwithlooseargs_int( i, );
callwithlooseargs_float( x );
callwithlooseargs_double( xx );
callwithlooseargs_string( "nice args, eh?" );

... then it's up to you to supply those functions.
So your "little preprocessor" can determine the type of each argument
and generate the appropriate code?

How is it going to handle things like this?

42
42 + 3.0
42ULL
rand()
arr[i]
struct_obj->foo[0]->bar[1]

I don't believe you can do this in general with a 7-line Perl program
(unless you have *very* long lines). To handle this correctly in all
cases, you really need a complete C parser and semantic analyzer --
basically a full C compiler except for code generation.

And none of it is really necessary. Presumably when you write a call
to your function, you know the types of the arguments. Just make your
"callwithlooseargs" a variadic function (using <stdarg.h>), and define
a mechanism to allow the caller to specify the types of the arguments.
For example, you might precede each argument with something that
specifies its type:

enum arg_type { ARG_INT, ARG_FLOAT, ARG_DOUBLE, ARG_STRING };
void callwithlooseargs(enum arg_type first_type, ...);
...
callwithlooseargs(ARG_INT, i,
ARG_FLOAT, x,
ARG_DOUBLE, xx,
ARG_STRING, "nice args, eh?");

Since <stdarg.hrequires one non-variadic function, you need to treat
the first argument specially (unless you have one or more fixed
arguments anyway). Processing the arguments with va_start, va_arg,
and va_end is fairly straightforward.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 6 '06 #8
>"Ancient_Hacker" <gr**@comcast.netwrites:
[snippage]
> callwithlooseargs( i, x, xx, "nice args, eh?" ); /*<i f d s <>*/
[fed through a script to ...]
>and generate this:

callwithlooseargs_int( i, );
callwithlooseargs_float( x );
callwithlooseargs_double( xx );
callwithlooseargs_string( "nice args, eh?" );

... then it's up to you to supply those functions.
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>So your "little preprocessor" can determine the type of each argument
and generate the appropriate code?
I think (although I am just guessing) that the intent here is to
use the "<>" comment to supply the types.

This is (at least arguably) more efficient than having the function
pluck them out of type arguments with <stdarg.h>:
>... [using stdarg.h,] you might precede each argument with
something that specifies its type:

enum arg_type { ARG_INT, ARG_FLOAT, ARG_DOUBLE, ARG_STRING };
void callwithlooseargs(enum arg_type first_type, ...);
...
callwithlooseargs(ARG_INT, i,
ARG_FLOAT, x,
ARG_DOUBLE, xx,
ARG_STRING, "nice args, eh?");
You will need a count of arguments (kind of error-prone, in my
opinion) or a "terminator type" (ARG_END or some such).
>Since <stdarg.hrequires one non-variadic function, you need to treat
the first argument specially (unless you have one or more fixed
arguments anyway). Processing the arguments with va_start, va_arg,
and va_end is fairly straightforward.
But it does add run-time overhead, which the preprocessor avoids.
On the other hand, preprocessing one call into four adds runtime
call overhead, which the variable-argument list technique avoids.
The relative speed of the two techniques is going to be rather
architecture-dependent; unless/until tested during an optimization
phase, I would write whichever one is easier to get right.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Aug 6 '06 #9
Chris Torek <no****@torek.netwrites:
>>"Ancient_Hacker" <gr**@comcast.netwrites:
[snippage]
>> callwithlooseargs( i, x, xx, "nice args, eh?" ); /*<i f d s <>*/
[fed through a script to ...]
>>and generate this:

callwithlooseargs_int( i, );
callwithlooseargs_float( x );
callwithlooseargs_double( xx );
callwithlooseargs_string( "nice args, eh?" );

... then it's up to you to supply those functions.

In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
>>So your "little preprocessor" can determine the type of each argument
and generate the appropriate code?

I think (although I am just guessing) that the intent here is to
use the "<>" comment to supply the types.
Ok, that's probably a good guess.
This is (at least arguably) more efficient than having the function
pluck them out of type arguments with <stdarg.h>:
>>... [using stdarg.h,] you might precede each argument with
something that specifies its type:

enum arg_type { ARG_INT, ARG_FLOAT, ARG_DOUBLE, ARG_STRING };
void callwithlooseargs(enum arg_type first_type, ...);
...
callwithlooseargs(ARG_INT, i,
ARG_FLOAT, x,
ARG_DOUBLE, xx,
ARG_STRING, "nice args, eh?");

You will need a count of arguments (kind of error-prone, in my
opinion) or a "terminator type" (ARG_END or some such).
You're right, of course.
>>Since <stdarg.hrequires one non-variadic function, you need to treat
the first argument specially (unless you have one or more fixed
arguments anyway). Processing the arguments with va_start, va_arg,
and va_end is fairly straightforward.

But it does add run-time overhead, which the preprocessor avoids.
On the other hand, preprocessing one call into four adds runtime
call overhead, which the variable-argument list technique avoids.
The relative speed of the two techniques is going to be rather
architecture-dependent; unless/until tested during an optimization
phase, I would write whichever one is easier to get right.
Indeed. Using a custom preprocessor to generate code is often useful,
but in this case I think it's more trouble than it's worth.

If it makes sense to *generate* calls to callwithlooseargs_int,
callwithlooseargs_float, et al, then IMHO, it makes sense just to
write calls to those functions directly.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Aug 6 '06 #10

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

Similar topics

1
by: Mike Kamermans | last post by:
Is there a way to determine what a node() find returns? For instance, if I have a snip of XSLT that looks like: <xsl:for-each select="node()"> ... </xsl:for-each> Is there a way to, for each...
3
by: Trevor M. Lango | last post by:
The number of arguments passed to the following functions can be determined - but how is this coded? main (int argc, char *argv) printf ( string format ) I would like to be able to write...
3
by: Steve Brown | last post by:
Hello all, Is there a way to determine a variable's type at run-time? The reason I'm asking is that i have code that looks like this: template <class T> Object::Object(int TypeCode, T* data)...
0
by: CTDev Team | last post by:
Hi, We are using Exchange Server 5.5, and have applications written in VB6 and C# that read and process emails. We are experiencing intermittent errors similar to C# Application ...
4
by: petermichaux | last post by:
Hi, I'm hoping for a reason I'm wrong or an alternate solution... I'd like to be able to dynamically include some javascript files. This is like scriptaculous.js library but their solution is...
5
by: Doug Stiers | last post by:
C# newbie question: I'm trying to determine the type of a datareader value. Why cant I do it like this? if (rdr.GetValue(0).GetType() is Guid || rdr.GetValue(0).GetType() is Int32) { // do...
5
by: Jeremy | last post by:
Does anyone have a clever algorithm for generating an outline of the current document from (client-side) javascript using DOM methods? For example, let's say I predictably have a document...
2
by: pob | last post by:
I was all happy because thru some tutelage of others I created this array to find the newest file in a directory. However, I then realized its great that I now know the latest file, but I need to...
4
by: mouseit | last post by:
If I have a variable of some sort, say x, how can I find out what variable type javascript thinks it is? For example, if I've declared x as 5 earlier, how do I know now whether it's a string or a...
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
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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
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,...
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...

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.