sandeep said:
Sometimes I imagine that you and Mr Sosmanji just look for reasons to
oppose my suggestions...
Not really. In this case, I merely pointed out that your suggestion is
based on incorrect assumptions and cannot be implemented in standard C
as it exists now. The only reason I disagreed with you is that you
were wrong.
Obviously the implementation can "work magic" and do anything by
functions.
But the true point is that if the problem is not being able to pass type
names to functions, but being able to pass them to macros, why not
improve the language to allow *all* functions (both implementation and
user functions) to accept type names as arguments? This would also be
very helpful for type-generic / template-based programming which is now
very difficult in C.
Your original point was something quite different, that some things
in the standard library are defined as macros "to remove the function
call overhead". That is untrue; they're defined as macros because
they cannot be defined as functions in standard C.
And now you're introducing an entirely new point that you didn't
mention, or even hint at, in your original post.
But with an underlying function available, the user can make use of it
themself, eg by passing it as a callback to another function!
Certainly. The standard requires the underlying function to
be available, as it does for all standard functions. The only
special thing about getc is that *if* it's implemented as a macro
(in addition to the required implementation as a function), that
macro is permitted to evaluate its stream argument more than once.
You can still pass the address of the getc function to another
function for use as a callback.
The vast majority of entities in the standard library that can
be invoked using syntax that looks like a function call *must*
be implemented as functions, and in addition *may* be implemented
as macros (which can be bypassed to get to the actual function).
Just one such entity, getc(), comes with permission for the macro
to evaluate its argument more than once. This provides significant
performance benefits, though I suspect an inline function could
provide similar benefits. You might have a valid point that the
special permission for getc() is obsolete, but I haven't thought
about it in any detail.
offsetof() takes a type name as its first argument, and a member
name as its second argument. In C as it's currently defined, it's
simply not possible for it to be defined as a function. (It's not
even possible to define it as a macro in portable C, which is part
of why it's in the standard library; implementations can implement
as a macro taking advantage of non-portable assumptions.)
Ok, so you want to enhance the language so offsetof() *can* be
implemented as a function (something you didn't mention in your
initial post). How would you do that? Can you show us a proposed
implementation of offsetof() as a function in an extended C?
How would the parameters be declared? How would the body of the
function refer to them?
As for assert(), it's a macro because it needs to refer to the values
of __FILE__, __LINE__, and __func__ *at the point of the call*.
This is source-level information that is not available to functions.
Permitting type names as function parameters wouldn't help.
How would you write assert() as a function in an extended ?
va_arg(), va_copy(), va_end(), va_start(): Same questions.
Oh, and setjmp() saves its calling environment; how would you write
that in an extended C?
If you want to require all these things to be functions, you're
going to have to show us how.