comp.lang.ada
 help / color / mirror / Atom feed
* Variable arguments magic in Ada to C code
@ 2002-08-05 23:47 Andreas Almroth
       [not found] ` <slrnakv5v0.p2.lutz@taranis.iks-jena.de>
  0 siblings, 1 reply; 10+ messages in thread
From: Andreas Almroth @ 2002-08-05 23:47 UTC (permalink / raw)


G'day netfolks,

I'm this close <--> declaring my self dummy in Ada, which could very well be
true... ;-)

I'm trying to create a variable argument list in my Ada code, to a piece of
C code. The C code works fine on several platforms, so I'm quite sure I'm 
the one doing wrong... :-(

I searched google and found a few quite valuable replies to this question,
but I have found that my implementation is still not working. I'm developing
on Sun SPARC with Solaris 8, and just can't get my code to work.
The first argument passed works just fine, but the rest are not interpreted
very well by the C code. An 32/64 bits issue?

I have checked the GNAT source code, and I have tried to do the same thing
as they do there, but can't get it to work. I also need to transfer pointers 
to other types than strings (assuming this might prove harder than I thought).

Well, before publishing my code to further scrutiny and laughter, I thought
I would ask this kind newsgroup to pointers of information, or even better, to
working examples (other than GNAT source)...

Kind regards,
Andreas

--
Remove -nntp to mail directly








^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Variable arguments magic in Ada to C code
       [not found]       ` <dstanbro-CDC252.20502007082002@news-server.bigpond.net.au>
@ 2002-08-14  9:05         ` Lutz Donnerhacke
  0 siblings, 0 replies; 10+ messages in thread
From: Lutz Donnerhacke @ 2002-08-14  9:05 UTC (permalink / raw)


* Dale Stanbrough wrote:
>Lutz Donnerhacke wrote:
>> >Anyway, I think I'm heading the right way, found the X11Ada binding which
>> >includes a stdarg package doing just what I want. This excellent package
>> >is written by Mitch Gart.
>> 
>> Personally I find this package horrible. It will take some minutes before I
>> can eat something again.
>
>Strange reaction. Perhaps you should move to another business.

This is no option.

>If you need to interface to software written using varargs, then I'm
>not sure what you are suggesting one should do.

Offer the strong typing features by declaring each argument count as a
seperate function/procedure. Import those from the same linker name. This is
recommended in the ARM. It works. If you need also variable argument types,
use generics for Import.

If you need to provide such a function, you have to use a completely
different approach: You have to have a deep look into the calling system of
your other world compiler ...



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Variable arguments magic in Ada to C code
       [not found] ` <slrnakv5v0.p2.lutz@taranis.iks-jena.de>
       [not found]   ` <87ptww7yj6.fsf@almroth.com>
@ 2002-08-14 10:01   ` Florian Weimer
  2002-08-14 11:34     ` Lutz Donnerhacke
  1 sibling, 1 reply; 10+ messages in thread
From: Florian Weimer @ 2002-08-14 10:01 UTC (permalink / raw)


lutz@iks-jena.de (Lutz Donnerhacke) writes:

> * Andreas Almroth wrote:
>>The first argument passed works just fine, but the rest are not interpreted
>>very well by the C code. An 32/64 bits issue?
>
> No, but I do not understand the problem:
> ARM B.3 says in Note (12):
>    A C function that takes a variable number of arguments can correspond to
>    several Ada subprograms, taking various specific numbers and types of
>    parameters.

The calling convention of a C function which expects a variable number
of arguements can differ considerably from one which does not.

Your example is not portable.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Variable arguments magic in Ada to C code
  2002-08-14 10:01   ` Florian Weimer
@ 2002-08-14 11:34     ` Lutz Donnerhacke
  2002-08-14 13:13       ` Dale Stanbrough
  2002-08-14 13:59       ` Florian Weimer
  0 siblings, 2 replies; 10+ messages in thread
From: Lutz Donnerhacke @ 2002-08-14 11:34 UTC (permalink / raw)


* Florian Weimer wrote:
>lutz@iks-jena.de (Lutz Donnerhacke) writes:
>> * Andreas Almroth wrote:
>>>The first argument passed works just fine, but the rest are not interpreted
>>>very well by the C code. An 32/64 bits issue?
>>
>> No, but I do not understand the problem:
>> ARM B.3 says in Note (12):
>>    A C function that takes a variable number of arguments can correspond to
>>    several Ada subprograms, taking various specific numbers and types of
>>    parameters.
>
>The calling convention of a C function which expects a variable number
>of arguements can differ considerably from one which does not.

This would cause major problems when compiling legal C code without advanced
prototypes for such function.

>Your example is not portable.

What is the portable (right(TM)) solution?



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Variable arguments magic in Ada to C code
  2002-08-14 11:34     ` Lutz Donnerhacke
@ 2002-08-14 13:13       ` Dale Stanbrough
  2002-08-14 13:59       ` Florian Weimer
  1 sibling, 0 replies; 10+ messages in thread
From: Dale Stanbrough @ 2002-08-14 13:13 UTC (permalink / raw)


Lutz Donnerhacke wrote:

> What is the portable (right(TM)) solution?


Perhaps the portable solution is to fully document
how you determine what the calling conventions for 
a C Vararg list are.

Unless of course it makes you queasy...

Dale



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Variable arguments magic in Ada to C code
  2002-08-14 11:34     ` Lutz Donnerhacke
  2002-08-14 13:13       ` Dale Stanbrough
@ 2002-08-14 13:59       ` Florian Weimer
  2002-08-14 14:02         ` Lutz Donnerhacke
  1 sibling, 1 reply; 10+ messages in thread
From: Florian Weimer @ 2002-08-14 13:59 UTC (permalink / raw)


lutz@iks-jena.de (Lutz Donnerhacke) writes:

>>The calling convention of a C function which expects a variable number
>>of arguements can differ considerably from one which does not.
>
> This would cause major problems when compiling legal C code without
> advanced prototypes for such function.

Yes, these problems exist.  So what?

>>Your example is not portable.
>
> What is the portable (right(TM)) solution?

Writing intermediate C wrappers?



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Variable arguments magic in Ada to C code
  2002-08-14 13:59       ` Florian Weimer
@ 2002-08-14 14:02         ` Lutz Donnerhacke
  2002-08-15 10:09           ` Florian Weimer
  0 siblings, 1 reply; 10+ messages in thread
From: Lutz Donnerhacke @ 2002-08-14 14:02 UTC (permalink / raw)


* Florian Weimer wrote:
>lutz@iks-jena.de (Lutz Donnerhacke) writes:
>>>The calling convention of a C function which expects a variable number
>>>of arguements can differ considerably from one which does not.
>>
>> This would cause major problems when compiling legal C code without
>> advanced prototypes for such function.
>
>Yes, these problems exist.  So what?

I can't believe such a brain damage. There must be something really huge
hitting and smashing the inventors head.

>>>Your example is not portable.
>>
>> What is the portable (right(TM)) solution?
>
>Writing intermediate C wrappers?

*wrgs*



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Variable arguments magic in Ada to C code
  2002-08-14 14:02         ` Lutz Donnerhacke
@ 2002-08-15 10:09           ` Florian Weimer
  2002-08-18 22:43             ` David Thompson
  0 siblings, 1 reply; 10+ messages in thread
From: Florian Weimer @ 2002-08-15 10:09 UTC (permalink / raw)


lutz@iks-jena.de (Lutz Donnerhacke) writes:

>>>>The calling convention of a C function which expects a variable number
>>>>of arguements can differ considerably from one which does not.
>>>
>>> This would cause major problems when compiling legal C code without
>>> advanced prototypes for such function.
>>
>>Yes, these problems exist.  So what?
>
> I can't believe such a brain damage. There must be something really huge
> hitting and smashing the inventors head.

Quite a lot of GNU C code breaks when compiled with a conforming
C compiler because prototypes do not match old-style function
definitions (I'm not sure if prototypes were allowed at all for
old-style function definitions before C99).



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Variable arguments magic in Ada to C code
       [not found]       ` <87vg6nj8jd.fsf@almroth.com>
@ 2002-08-16 19:41         ` David Thompson
  0 siblings, 0 replies; 10+ messages in thread
From: David Thompson @ 2002-08-16 19:41 UTC (permalink / raw)


Andreas Almroth <andreas-nntp@almroth.com> wrote :
> lutz@iks-jena.de (Lutz Donnerhacke) writes:
[ calling C variable-argument functions ]
> Well, I'm merely interfacing to an existing C library. I do heaps of type-
> and value checking before passing on to the C function, and thus trying to
> limit the consequences of incorrect arguments.
...
> > >When using VA in C, you build a list of pointers (System.Address) to your
> > >arguments, and terminate the list with NULL (Null_Ptr).
> >
Not true, at least not in general.  The actual argument-passing
mechanism(s), for both vararg and non-vararg functions, are not
defined by the C standard only by implementation(s) (so in principle
you need to say not "in C" but "in MSVC++6" or "in gcc 3.0" etc.),
but in practice at least varargs are passed in consecutive memory
(modulo padding needed for alignment) usually on the stack or
possibly in other "standard" (for the platform/architecture) places
like the VAX AP-addressed arglist or S/370 R1->caller memory.

For _some_ functions, some or even all of these arguments
are pointers, e.g. the *scanf family and in Unix/POSIX execl*.
The latter are terminated by a null pointer; the former are not.
For other functions, like *printf, (most of) the arguments are
not pointers at all.

There is an important distinction however between a function
which actually takes variable arguments, and a function which
takes a va_list (or pointer thereto), which is a single, fixed,
but opaque and implementation-dependent type that allows
the callee to access the variable-arguments of the _caller_.

> > No. You pass a controlling argument which is parsed and interpreted by the
> > called function. In my previous example it was simply a count value.
> >
Usually but not necessarily.  What is absolutely true is that
the called function must (be able to) determine the number
and type(s) of arguments somehow _before_ accessing them --
no checking or conversion is provided by the varargs mechanism.
This _may_ be the format specifier substrings in *printf/*scanf,
a null or other sentinel value as in execl*, a count,
or anything else you care to code that works for your data.
It _could_ be global/shared data, or a callback function,
or something even more bizarre, although if you do such things
don't expect anyone else to accept or reuse your code.

> > Inband-terminated arrays are used to pass arrays in C. In Ada you pass the
> > array bounds out of band, so you never need this data manipulation.
> >
Actually inband termination is mostly used in C for array of
character representing a string.  Arrays of other types are
(more?) commonly dimensioned by counts passed explicitly
or implicit in e.g. global state, and sentinel values IME rather
rarer though certainly used in some cases.

> > >You then pass the pointer to the list, as the last argument to the C
> > >function. With the VA_* macros you then traverse the pointers and type
> > >cast to whatever suitable (as in printf, you know by the format string
> > >what to expect).
> >
> > No, this is not the way stdarg works. You access the first few arguments of
> > the function and the iterativly get the next argument. There is no problem
> > in causing strange errors by calling a function with the wrong number of
> > arguments. The called function will reinterpret the stack as arguments or
> > crash or do something much more strange.
> >
>
To be a bit more specific:
The callee accesses all fixed arguments (parameters) as normal,
and the variable arguments iteratively using a va_list whose initialization
(by va_start) requires specifying the last fixed parameter (which must not
be of a type that gets automatically "adjusted") -- in practice this
(always?) accesses varargs which are passed in consecutive memory
either just after that last fixed argument or in a location determined by
the calling mechanism independent of the fixed argument(s),
and the va_list is really just a pointer that scans across that memory,
but that mechanism is not required.

Yes, if the callee does try to "receive" argument types that don't match
those the caller actually passed, except for a few minor variations
allowed by the default argument promotions and (arguably) type
compatibility rules, you get Undefined Behavior (= Ada erroneous)
which will typically do something Weird or Very Bad or both.

A vararg-callee can further pass its varargs (or a suffix of them)
as a block to lower-level routines, by passing the va_list.  It is
not defined whether va_list is an array type, and thus is effectively
passed by reference and shared rather than by value, so if you
need copy semantics -- that is you need to access the varargs
in both the direct-callee and a further-callee -- in C89 you can
and theoretically must create and destroy (va_end) separate or
disjoint va_list's, although in practice just copying the va_list
works, and C99 makes this official (va_copy).  For example,
printf can be implemented by just passing its arguments to
vprintf (or perhaps vfprintf) which does the actual work; you
can write your own vararg function which includes (modified)
printf semantics that also calls vprintf etc. etc.

(Aside:  saying that there is 'no problem' with something normally
connotes that it is OK, good, satisfactory, manageable.  I assume
you meant "there is no difficulty in causing (trouble)", but it is simpler
and IMO clearer to use the positive "it is easy to cause (trouble)".)

--
- David.Thompson 1 now at worldnet.att.net






^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: Variable arguments magic in Ada to C code
  2002-08-15 10:09           ` Florian Weimer
@ 2002-08-18 22:43             ` David Thompson
  0 siblings, 0 replies; 10+ messages in thread
From: David Thompson @ 2002-08-18 22:43 UTC (permalink / raw)


Florian Weimer <fw@deneb.enyo.de> wrote :
> lutz@iks-jena.de (Lutz Donnerhacke) writes:
...
> Quite a lot of GNU C code breaks when compiled with a conforming
> C compiler because prototypes do not match old-style function
> definitions (I'm not sure if prototypes were allowed at all for
> old-style function definitions before C99).

This is not very clear; I think you mean declarations using
prototype syntax (new in C89/90, like C++) in calling code
for a function whose definition (implementation, body) uses
old-style (K&R1) parameter declaration syntax.  If so, you
_can_ (since C89) write a prototype correctly matching any
definition that was legal in K&R1 -- but you must be careful,
because parameters of "less than normal width" types,
specifically integer types below (signed or unsigned) int
and float (the only floating type below double) were promoted
in K&R1 calls and thus the promoted types must be used
in the prototype to get the correct matching, even though
the definition can be written with the narrower type(s).

gcc will warn about mistakes here if the prototype declaration
is visible at the definition (e.g. by #include'ing the "spec" .h
in the "body", a commonly recommended practice) if you use
-pedantic, at least 2.95.2 which is what I have handy to check.

If this is meant to relate to the earlier posts about vararg versus
non-vararg functions in C, there was and is no K&R1 syntax
for vararg -- the _only_ correct way to call or define/implement
vararg functions in C is with prototype syntax.  (Or of course
a compatible implementation of another language, like Ada.)

--
- David.Thompson 1 now at worldnet.att.net








^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2002-08-18 22:43 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-05 23:47 Variable arguments magic in Ada to C code Andreas Almroth
     [not found] ` <slrnakv5v0.p2.lutz@taranis.iks-jena.de>
     [not found]   ` <87ptww7yj6.fsf@almroth.com>
     [not found]     ` <slrnal1l8s.pj.lutz@taranis.iks-jena.de>
     [not found]       ` <dstanbro-CDC252.20502007082002@news-server.bigpond.net.au>
2002-08-14  9:05         ` Lutz Donnerhacke
     [not found]       ` <87vg6nj8jd.fsf@almroth.com>
2002-08-16 19:41         ` David Thompson
2002-08-14 10:01   ` Florian Weimer
2002-08-14 11:34     ` Lutz Donnerhacke
2002-08-14 13:13       ` Dale Stanbrough
2002-08-14 13:59       ` Florian Weimer
2002-08-14 14:02         ` Lutz Donnerhacke
2002-08-15 10:09           ` Florian Weimer
2002-08-18 22:43             ` David Thompson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox