getting variable type in C

S

suman kar

Of course you are right in saying that a runtime operator for
getting an object's type doesn't make much sense in C.

I am not sure, however, if I would characterize gcc's typeof()
as a "band-aid for macros". Calling it band-aid implies that
there may be a better solution in sight. Look at:

#define swap(a,b) do \
{ typeof(a) swap_tmp = a; a = b; b = swap_tmp; } while(0)

The alternative is to write a different swap macro/function for
each different type. Which is the cleaner? Which is the band-aid?

One more alternative:reading up on K&R, they did it years ago without
any typeof operator.Hint:pass the type as a parameter.
A more interesting and useful application of a typeof()
construct would be in the dynamic allocation of two-dimensional
arrays. Instead of having to supply multiple functions such as:

double **make_matrix_double (size_t m, size_t n);
int **make_matrix_int (size_t m, size_t n);
complex **make_matrix_complex (size_t m, size_t n);
mystruct **make_matrix_mystruct(size_t m, size_t n);

you may write a single make_matrix() macro for all types.
Very handy for numerical analysts working with matrix algebra.
I wouldn't dismiss this an "odd occasion where it is useful".

HTH.
Suman.
 
D

Dan Pop

In said:
For this and similar kind of macros I pass the type in argument:

#define SWAP(type, a, b) do \
{ type swap_tmp = a; a = b; b = swap_tmp; } while(0)

SWAP(struct mystruct, a, b);

If you pass the temp object instead, the macro definition is much
simpler and invoking the thing really looks like a function call:

#define SWAP(a, b, t) (t = a, a = b, b = t)

SWAP(a, b, tmp);

Most of the time you already have an object of the right type available
to be used as the third argument.

Dan
 
S

S.Tobias

If you pass the temp object instead, the macro definition is much
simpler and invoking the thing really looks like a function call:
#define SWAP(a, b, t) (t = a, a = b, b = t)
SWAP(a, b, tmp);

Agreed, but still I prefer passing the type rather than an object.
Here's why:

Some algorithms might require more than one temp object. Having
to pass different number of temp arguments to different macros
would be clumsy. Passing the type I gain *uniform interface*.

When changing the algorithm, the new one could require more
temp objects; in this case I would have to change number of
parameters and subsequently change all macro calls. When
I pass the type, macro expansion can generate as many local
temp variables as it needs. This way I achieve *stable interface*.

In both methods you have to know the type - you have to write
it either at temp object declaration or as an argument to macro.
If typeof() was standard, we wouldn't have to think about the
type. Anyway, my method a little resembles C++ templates:
template<class type> void swap(type a, type b) { type t=a; a=b; b=t; }
swap<int>(x, y); <-> SWAP(int, x, y);

I think the difference can be perceived when constructing macros
with nested macro calls: it's extremely convenient to just pass the
type:
#define MACRO(type, x, y) do{ MAC_A(type, x); MAC_B(type, x, y); }while(0)
#define MAC_A(type, x) /*...*/
#define MAC_B(type, x, y) /*...*/

And, of course, inside a macro definition I wouldn't name a temp
object "swap_tmp", but rather "swap_tmp_200411172322" (my efficiency
at present is below one temporary variable per minute).
 
D

Dan Pop

In said:
Agreed, but still I prefer passing the type rather than an object.
Here's why:

Some algorithms might require more than one temp object.

Such algorithms are highly unlikely to get implemented as macros.
When changing the algorithm, the new one could require more
temp objects;

When was the last time you've made such a change to a macro?

If it's not something very straightforward, you probably don't want to
implement it as a macro. Otherwise, debugging and maintenance become
a nightmare.

Multiple temps are nice when you want to write macros with true function
call semantics, to avoid multiple evaluation of the macro parameters.
However, I can happily live with multiple evaluations and never include
side effects in the expressions passed as arguments to macros. I usually
avoid such expressions even in genuine function calls.

Dan
 
K

Kenny McCormack

Sure. Just take the type it was at compile time, and remember it.
For example,

int main(void)
{
int i;
printf("i is of type %s.\n", "int");
return 0;
}

If you have some other idea in mind, you're going to have to be more
explicit.

It would be interesting to know what the OP really had in mind.
Unfortunately, seems to be a case of "post-and-run".

Maybe he is thinking of textual analysis on the source code. Like, here's
a bunch of *.c files - what type is variable "foo".
 
D

Dan Pop

In said:
How would you want this information to be represented? How would you use
it? Remember that C is statically typed. You know at the point you use
a variable what type it is, you just have to look at the definition for
the variable.


AFAIK this is just a band-aid for macros, replicating a type in
another declaration or a cast - strictly a compile time thing. It doesn't
address the OP's question of a runtime test.

True. The GNU C feature for runtime type testing is the function
__builtin_types_compatible_p(type1, type2) and not the typeof operator.

It is impossible to implement things like <tgmath.h> without this kind of
tool. And it's quite handy for writing your own type generic macros, but,
unfortunately, the C standard doesn't also provide the tools required for
implementing its own headers.
Since C doesn't support
Runtime Type Information, inheritance or any sort of dynamic typing a
runtime test doesn't make much sense - it just tells you what you already
know.

Not true when implementing macros with parameters.
There may be the odd occasion where it is useful but don't see that these
are common enough to make it a language requirement.

typeof is a must for any *decent* type generic macro needing temporary
variables. Without it, the macro needs additional arguments specifying
either the types of the temps or the names of the temps. Trivial
example: a type generic SWAP(x, y).

Dan
 
D

Dan Pop

In said:
I didn't claim that band-aids aren't useful.

You can consider the C language itself as a band-aid for people who cut
themselves with assembly.
But are examples like this
enough to warrant an extra feature in the language?

Well, they're far more useful to me than most of the new features of C99.
IIRC typeof seemed like a good idea to me in 1999, but I don't
see its failure to get into C99 as a great problem.

It is such failures that explain the failure of C99 as a whole. If C99
actually provided most extensions *C* programmers keep asking for, the
demand for C99 implementations would have been high enough to have C89
actually replaced by C99 in the real world.

Dan
 
M

Mark F. Haigh

Kenny McCormack wrote:
>
Stick around for a bit, and you will come to understand more things about
this very religious newsgroup.

One of the fundamental tenents of this religion is that if it is not
standard, it is *not C* (1). That is, the claim is not that it is merely
"not standard C", but that it is not C at all. Bog knows what it is (for
all they care, it might be Fortran or Frobozz or your left ear), but
neither of the following are in any sense written or in any way related to
the C language:
<snip>

Here, "C" is commonly used as shorthand for "standard C". Are you still
struggling with this concept?


(1) And that fact is enforced by a bunch of religious Nazis (get it, not C,
nazi, heh heh)

How horribly unbearable! I'll have mama get us some ginger snaps and
warm milk before bedtime!



Mark F. Haigh
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,154
Messages
2,570,870
Members
47,400
Latest member
FloridaFvt

Latest Threads

Top