From: JB on
On 2010-05-26, glen herrmannsfeldt <gah(a)ugcs.caltech.edu> wrote:
> [Argument passing in C]
>
> First, anything smaller than int is always converted to int
> before the call.

Really? I wasn't aware of that. Is this something specified in the C
standard, or is it just implemented this way on some (common?) ABI's?

> Next, if a prototype is in scope (usually from a #include file)
> then it will be converted as appropriate.

Oh, so the above applies only when calling functions without a
prototype?

I believe C99 made it an error to call a function without a
prototype. And for good reasons - similar to the use of implicit
vs. explicit interfaces in Fortran.

I recall one episode a few years ago when someone (on an internal
mailing list) got nonsense results when trying to use the C99 round()
function, which has the prototype

double round(double x);

At first the blame was laid on the glibc implementation of round(),
but the real reason turned out to be that the user hadn't compiled
with C99 mode, and the prototype for round() is hidden away behind
some #ifdefs which are set only in C99 mode, and then the compiler
went and created an implicit prototype

int rount(int);

However, the round symbol was still found in the library, so the
binary linked just fine, but produced nonsense results.

The moral of the story being, explicit interfaces are good, and pay
attention to the compiler warning and error messages. Both of which
apply to Fortran as well. :)

>> Yes, you can do something simillar to a type cast, but it creates a
>> duplicate, which you said you don't want to do. See the INT intrinsic
>> function. INT(an_integer_expression_of_any_kind, kind=c_size_t)
>> will cast the expression to the specified kind. However, that amounts to
>> a copy. Also, you can't use that to return information. But then I see
>> that you have the VALUE attribute, which already implies that you would
>> not be returning information anyway.
>
>> Maybe when you said you didn't want to create a duplicate, you just
>> meant that you didn't want to have a separate variable and manually copy
>> the data to it. You can avoid that, but you can't literally avoid making
>> a copy at all. (Heck, the VALUE attribute already implies a copy behind
>> your back.)
>
> But will there be two copies, one to C_SIZE_T, and then another
> for the VALUE attribute?

In principle, but it's entirely possible that the optimizer will be
able to remove the first one, and construct the typecast variable
directly on the stack or in some specific register, depending on where
the ABI requires procedure call arguments to be placed. Assuming that
the typecast variable is not used after the call, that is.

> (And especially as C_SIZE_T is the same
> as C_INT on many C implementations.

One rather common exception being x86_64, where in all ABI's I'm aware
of, int is a signed 32-bit integer, and size_t an unsigned 64-bit
integer.

--
JB
From: Tim Prince on
On 5/25/2010 7:45 PM, bio_amateur wrote:
> I just posted this in PGI Forum, yet i hope I can get more help from
> the comp.lang.fortran group mems.
>
> I believe that size_t interoperable type in Fortran is
> INTEGER(c_size_t). Suppose that I have a C function which accepts an
> integer of type size_t.
> If this function is called in C code, we can pass an integer constant
> or an integer variable of type int without any error.
> However, when I call it from Fortran, it doesn't allow me to pass a
> variable of type INTEGER, i.e. it requires the variable to be of the
> same KIND and TYPE also.

Your Fortran compiler is aware of the existence of platforms where C
makes a distinction between int and size_t, such as the most popular
64-bit platforms.
Since the year when I lost several months working with an outfit which
refused to complete a project on account of their disagreement with this
aspect of C++, the following discussion has appeared:
http://www.embedded.com/columns/programmingpointers/200900195

showing that it's not only 64-bit platforms which may make use of the
feature.


--
Tim Prince