1 \input texinfo @c -*-texinfo-*- 2 @c %**start of header 3 @setfilename libffi.info 4 @settitle libffi 5 @setchapternewpage off 6 @c %**end of header 7 8 @c Merge the standard indexes into a single one. 9 @syncodeindex fn cp 10 @syncodeindex vr cp 11 @syncodeindex ky cp 12 @syncodeindex pg cp 13 @syncodeindex tp cp 14 15 @include version.texi 16 17 @copying 18 19 This manual is for Libffi, a portable foreign-function interface 20 library. 21 22 Copyright @copyright{} 2008, 2010, 2011 Red Hat, Inc. 23 24 @quotation 25 Permission is granted to copy, distribute and/or modify this document 26 under the terms of the GNU General Public License as published by the 27 Free Software Foundation; either version 2, or (at your option) any 28 later version. A copy of the license is included in the 29 section entitled ``GNU General Public License''. 30 31 @end quotation 32 @end copying 33 34 @dircategory Development 35 @direntry 36 * libffi: (libffi). Portable foreign-function interface library. 37 @end direntry 38 39 @titlepage 40 @title Libffi 41 @page 42 @vskip 0pt plus 1filll 43 @insertcopying 44 @end titlepage 45 46 47 @ifnottex 48 @node Top 49 @top libffi 50 51 @insertcopying 52 53 @menu 54 * Introduction:: What is libffi? 55 * Using libffi:: How to use libffi. 56 * Missing Features:: Things libffi can't do. 57 * Index:: Index. 58 @end menu 59 60 @end ifnottex 61 62 63 @node Introduction 64 @chapter What is libffi? 65 66 Compilers for high level languages generate code that follow certain 67 conventions. These conventions are necessary, in part, for separate 68 compilation to work. One such convention is the @dfn{calling 69 convention}. The calling convention is a set of assumptions made by 70 the compiler about where function arguments will be found on entry to 71 a function. A calling convention also specifies where the return 72 value for a function is found. The calling convention is also 73 sometimes called the @dfn{ABI} or @dfn{Application Binary Interface}. 74 @cindex calling convention 75 @cindex ABI 76 @cindex Application Binary Interface 77 78 Some programs may not know at the time of compilation what arguments 79 are to be passed to a function. For instance, an interpreter may be 80 told at run-time about the number and types of arguments used to call 81 a given function. @samp{Libffi} can be used in such programs to 82 provide a bridge from the interpreter program to compiled code. 83 84 The @samp{libffi} library provides a portable, high level programming 85 interface to various calling conventions. This allows a programmer to 86 call any function specified by a call interface description at run 87 time. 88 89 @acronym{FFI} stands for Foreign Function Interface. A foreign 90 function interface is the popular name for the interface that allows 91 code written in one language to call code written in another language. 92 The @samp{libffi} library really only provides the lowest, machine 93 dependent layer of a fully featured foreign function interface. A 94 layer must exist above @samp{libffi} that handles type conversions for 95 values passed between the two languages. 96 @cindex FFI 97 @cindex Foreign Function Interface 98 99 100 @node Using libffi 101 @chapter Using libffi 102 103 @menu 104 * The Basics:: The basic libffi API. 105 * Simple Example:: A simple example. 106 * Types:: libffi type descriptions. 107 * Multiple ABIs:: Different passing styles on one platform. 108 * The Closure API:: Writing a generic function. 109 * Closure Example:: A closure example. 110 @end menu 111 112 113 @node The Basics 114 @section The Basics 115 116 @samp{Libffi} assumes that you have a pointer to the function you wish 117 to call and that you know the number and types of arguments to pass 118 it, as well as the return type of the function. 119 120 The first thing you must do is create an @code{ffi_cif} object that 121 matches the signature of the function you wish to call. This is a 122 separate step because it is common to make multiple calls using a 123 single @code{ffi_cif}. The @dfn{cif} in @code{ffi_cif} stands for 124 Call InterFace. To prepare a call interface object, use the function 125 @code{ffi_prep_cif}. 126 @cindex cif 127 128 @findex ffi_prep_cif 129 @defun ffi_status ffi_prep_cif (ffi_cif *@var{cif}, ffi_abi @var{abi}, unsigned int @var{nargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes}) 130 This initializes @var{cif} according to the given parameters. 131 132 @var{abi} is the ABI to use; normally @code{FFI_DEFAULT_ABI} is what 133 you want. @ref{Multiple ABIs} for more information. 134 135 @var{nargs} is the number of arguments that this function accepts. 136 137 @var{rtype} is a pointer to an @code{ffi_type} structure that 138 describes the return type of the function. @xref{Types}. 139 140 @var{argtypes} is a vector of @code{ffi_type} pointers. 141 @var{argtypes} must have @var{nargs} elements. If @var{nargs} is 0, 142 this argument is ignored. 143 144 @code{ffi_prep_cif} returns a @code{libffi} status code, of type 145 @code{ffi_status}. This will be either @code{FFI_OK} if everything 146 worked properly; @code{FFI_BAD_TYPEDEF} if one of the @code{ffi_type} 147 objects is incorrect; or @code{FFI_BAD_ABI} if the @var{abi} parameter 148 is invalid. 149 @end defun 150 151 If the function being called is variadic (varargs) then 152 @code{ffi_prep_cif_var} must be used instead of @code{ffi_prep_cif}. 153 154 @findex ffi_prep_cif_var 155 @defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi var{abi}, unsigned int @var{nfixedargs}, unsigned int var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes}) 156 This initializes @var{cif} according to the given parameters for 157 a call to a variadic function. In general it's operation is the 158 same as for @code{ffi_prep_cif} except that: 159 160 @var{nfixedargs} is the number of fixed arguments, prior to any 161 variadic arguments. It must be greater than zero. 162 163 @var{ntotalargs} the total number of arguments, including variadic 164 and fixed arguments. 165 166 Note that, different cif's must be prepped for calls to the same 167 function when different numbers of arguments are passed. 168 169 Also note that a call to @code{ffi_prep_cif_var} with 170 @var{nfixedargs}=@var{nototalargs} is NOT equivalent to a call to 171 @code{ffi_prep_cif}. 172 173 @end defun 174 175 176 To call a function using an initialized @code{ffi_cif}, use the 177 @code{ffi_call} function: 178 179 @findex ffi_call 180 @defun void ffi_call (ffi_cif *@var{cif}, void *@var{fn}, void *@var{rvalue}, void **@var{avalues}) 181 This calls the function @var{fn} according to the description given in 182 @var{cif}. @var{cif} must have already been prepared using 183 @code{ffi_prep_cif}. 184 185 @var{rvalue} is a pointer to a chunk of memory that will hold the 186 result of the function call. This must be large enough to hold the 187 result, no smaller than the system register size (generally 32 or 64 188 bits), and must be suitably aligned; it is the caller's responsibility 189 to ensure this. If @var{cif} declares that the function returns 190 @code{void} (using @code{ffi_type_void}), then @var{rvalue} is 191 ignored. 192 193 @var{avalues} is a vector of @code{void *} pointers that point to the 194 memory locations holding the argument values for a call. If @var{cif} 195 declares that the function has no arguments (i.e., @var{nargs} was 0), 196 then @var{avalues} is ignored. Note that argument values may be 197 modified by the callee (for instance, structs passed by value); the 198 burden of copying pass-by-value arguments is placed on the caller. 199 @end defun 200 201 202 @node Simple Example 203 @section Simple Example 204 205 Here is a trivial example that calls @code{puts} a few times. 206 207 @example 208 #include <stdio.h> 209 #include <ffi.h> 210 211 int main() 212 @{ 213 ffi_cif cif; 214 ffi_type *args[1]; 215 void *values[1]; 216 char *s; 217 ffi_arg rc; 218 219 /* Initialize the argument info vectors */ 220 args[0] = &ffi_type_pointer; 221 values[0] = &s; 222 223 /* Initialize the cif */ 224 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 225 &ffi_type_sint, args) == FFI_OK) 226 @{ 227 s = "Hello World!"; 228 ffi_call(&cif, puts, &rc, values); 229 /* rc now holds the result of the call to puts */ 230 231 /* values holds a pointer to the function's arg, so to 232 call puts() again all we need to do is change the 233 value of s */ 234 s = "This is cool!"; 235 ffi_call(&cif, puts, &rc, values); 236 @} 237 238 return 0; 239 @} 240 @end example 241 242 243 @node Types 244 @section Types 245 246 @menu 247 * Primitive Types:: Built-in types. 248 * Structures:: Structure types. 249 * Type Example:: Structure type example. 250 * Complex:: Complex types. 251 * Complex Type Example:: Complex type example. 252 @end menu 253 254 @node Primitive Types 255 @subsection Primitive Types 256 257 @code{Libffi} provides a number of built-in type descriptors that can 258 be used to describe argument and return types: 259 260 @table @code 261 @item ffi_type_void 262 @tindex ffi_type_void 263 The type @code{void}. This cannot be used for argument types, only 264 for return values. 265 266 @item ffi_type_uint8 267 @tindex ffi_type_uint8 268 An unsigned, 8-bit integer type. 269 270 @item ffi_type_sint8 271 @tindex ffi_type_sint8 272 A signed, 8-bit integer type. 273 274 @item ffi_type_uint16 275 @tindex ffi_type_uint16 276 An unsigned, 16-bit integer type. 277 278 @item ffi_type_sint16 279 @tindex ffi_type_sint16 280 A signed, 16-bit integer type. 281 282 @item ffi_type_uint32 283 @tindex ffi_type_uint32 284 An unsigned, 32-bit integer type. 285 286 @item ffi_type_sint32 287 @tindex ffi_type_sint32 288 A signed, 32-bit integer type. 289 290 @item ffi_type_uint64 291 @tindex ffi_type_uint64 292 An unsigned, 64-bit integer type. 293 294 @item ffi_type_sint64 295 @tindex ffi_type_sint64 296 A signed, 64-bit integer type. 297 298 @item ffi_type_float 299 @tindex ffi_type_float 300 The C @code{float} type. 301 302 @item ffi_type_double 303 @tindex ffi_type_double 304 The C @code{double} type. 305 306 @item ffi_type_uchar 307 @tindex ffi_type_uchar 308 The C @code{unsigned char} type. 309 310 @item ffi_type_schar 311 @tindex ffi_type_schar 312 The C @code{signed char} type. (Note that there is not an exact 313 equivalent to the C @code{char} type in @code{libffi}; ordinarily you 314 should either use @code{ffi_type_schar} or @code{ffi_type_uchar} 315 depending on whether @code{char} is signed.) 316 317 @item ffi_type_ushort 318 @tindex ffi_type_ushort 319 The C @code{unsigned short} type. 320 321 @item ffi_type_sshort 322 @tindex ffi_type_sshort 323 The C @code{short} type. 324 325 @item ffi_type_uint 326 @tindex ffi_type_uint 327 The C @code{unsigned int} type. 328 329 @item ffi_type_sint 330 @tindex ffi_type_sint 331 The C @code{int} type. 332 333 @item ffi_type_ulong 334 @tindex ffi_type_ulong 335 The C @code{unsigned long} type. 336 337 @item ffi_type_slong 338 @tindex ffi_type_slong 339 The C @code{long} type. 340 341 @item ffi_type_longdouble 342 @tindex ffi_type_longdouble 343 On platforms that have a C @code{long double} type, this is defined. 344 On other platforms, it is not. 345 346 @item ffi_type_pointer 347 @tindex ffi_type_pointer 348 A generic @code{void *} pointer. You should use this for all 349 pointers, regardless of their real type. 350 351 @item ffi_type_complex_float 352 @tindex ffi_type_complex_float 353 The C @code{_Complex float} type. 354 355 @item ffi_type_complex_double 356 @tindex ffi_type_complex_double 357 The C @code{_Complex double} type. 358 359 @item ffi_type_complex_longdouble 360 @tindex ffi_type_complex_longdouble 361 The C @code{_Complex long double} type. 362 On platforms that have a C @code{long double} type, this is defined. 363 On other platforms, it is not. 364 @end table 365 366 Each of these is of type @code{ffi_type}, so you must take the address 367 when passing to @code{ffi_prep_cif}. 368 369 370 @node Structures 371 @subsection Structures 372 373 Although @samp{libffi} has no special support for unions or 374 bit-fields, it is perfectly happy passing structures back and forth. 375 You must first describe the structure to @samp{libffi} by creating a 376 new @code{ffi_type} object for it. 377 378 @tindex ffi_type 379 @deftp {Data type} ffi_type 380 The @code{ffi_type} has the following members: 381 @table @code 382 @item size_t size 383 This is set by @code{libffi}; you should initialize it to zero. 384 385 @item unsigned short alignment 386 This is set by @code{libffi}; you should initialize it to zero. 387 388 @item unsigned short type 389 For a structure, this should be set to @code{FFI_TYPE_STRUCT}. 390 391 @item ffi_type **elements 392 This is a @samp{NULL}-terminated array of pointers to @code{ffi_type} 393 objects. There is one element per field of the struct. 394 @end table 395 @end deftp 396 397 398 @node Type Example 399 @subsection Type Example 400 401 The following example initializes a @code{ffi_type} object 402 representing the @code{tm} struct from Linux's @file{time.h}. 403 404 Here is how the struct is defined: 405 406 @example 407 struct tm @{ 408 int tm_sec; 409 int tm_min; 410 int tm_hour; 411 int tm_mday; 412 int tm_mon; 413 int tm_year; 414 int tm_wday; 415 int tm_yday; 416 int tm_isdst; 417 /* Those are for future use. */ 418 long int __tm_gmtoff__; 419 __const char *__tm_zone__; 420 @}; 421 @end example 422 423 Here is the corresponding code to describe this struct to 424 @code{libffi}: 425 426 @example 427 @{ 428 ffi_type tm_type; 429 ffi_type *tm_type_elements[12]; 430 int i; 431 432 tm_type.size = tm_type.alignment = 0; 433 tm_type.type = FFI_TYPE_STRUCT; 434 tm_type.elements = &tm_type_elements; 435 436 for (i = 0; i < 9; i++) 437 tm_type_elements[i] = &ffi_type_sint; 438 439 tm_type_elements[9] = &ffi_type_slong; 440 tm_type_elements[10] = &ffi_type_pointer; 441 tm_type_elements[11] = NULL; 442 443 /* tm_type can now be used to represent tm argument types and 444 return types for ffi_prep_cif() */ 445 @} 446 @end example 447 448 @node Complex 449 @subsection Complex Types 450 451 @samp{libffi} supports the complex types defined by the C99 452 standard (@code{_Complex float}, @code{_Complex double} and 453 @code{_Complex long double} with the built-in type descriptors 454 @code{ffi_type_complex_float}, @code{ffi_type_complex_double} and 455 @code{ffi_type_complex_longdouble}. 456 457 Custom complex types like @code{_Complex int} can also be used. 458 An @code{ffi_type} object has to be defined to describe the 459 complex type to @samp{libffi}. 460 461 @tindex ffi_type 462 @deftp {Data type} ffi_type 463 @table @code 464 @item size_t size 465 This must be manually set to the size of the complex type. 466 467 @item unsigned short alignment 468 This must be manually set to the alignment of the complex type. 469 470 @item unsigned short type 471 For a complex type, this must be set to @code{FFI_TYPE_COMPLEX}. 472 473 @item ffi_type **elements 474 475 This is a @samp{NULL}-terminated array of pointers to 476 @code{ffi_type} objects. The first element is set to the 477 @code{ffi_type} of the complex's base type. The second element 478 must be set to @code{NULL}. 479 @end table 480 @end deftp 481 482 The section @ref{Complex Type Example} shows a way to determine 483 the @code{size} and @code{alignment} members in a platform 484 independent way. 485 486 For platforms that have no complex support in @code{libffi} yet, 487 the functions @code{ffi_prep_cif} and @code{ffi_prep_args} abort 488 the program if they encounter a complex type. 489 490 @node Complex Type Example 491 @subsection Complex Type Example 492 493 This example demonstrates how to use complex types: 494 495 @example 496 #include <stdio.h> 497 #include <ffi.h> 498 #include <complex.h> 499 500 void complex_fn(_Complex float cf, 501 _Complex double cd, 502 _Complex long double cld) 503 @{ 504 printf("cf=%f+%fi\ncd=%f+%fi\ncld=%f+%fi\n", 505 (float)creal (cf), (float)cimag (cf), 506 (float)creal (cd), (float)cimag (cd), 507 (float)creal (cld), (float)cimag (cld)); 508 @} 509 510 int main() 511 @{ 512 ffi_cif cif; 513 ffi_type *args[3]; 514 void *values[3]; 515 _Complex float cf; 516 _Complex double cd; 517 _Complex long double cld; 518 519 /* Initialize the argument info vectors */ 520 args[0] = &ffi_type_complex_float; 521 args[1] = &ffi_type_complex_double; 522 args[2] = &ffi_type_complex_longdouble; 523 values[0] = &cf; 524 values[1] = &cd; 525 values[2] = &cld; 526 527 /* Initialize the cif */ 528 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, 529 &ffi_type_void, args) == FFI_OK) 530 @{ 531 cf = 1.0 + 20.0 * I; 532 cd = 300.0 + 4000.0 * I; 533 cld = 50000.0 + 600000.0 * I; 534 /* Call the function */ 535 ffi_call(&cif, (void (*)(void))complex_fn, 0, values); 536 @} 537 538 return 0; 539 @} 540 @end example 541 542 This is an example for defining a custom complex type descriptor 543 for compilers that support them: 544 545 @example 546 /* 547 * This macro can be used to define new complex type descriptors 548 * in a platform independent way. 549 * 550 * name: Name of the new descriptor is ffi_type_complex_<name>. 551 * type: The C base type of the complex type. 552 */ 553 #define FFI_COMPLEX_TYPEDEF(name, type, ffitype) \ 554 static ffi_type *ffi_elements_complex_##name [2] = @{ \ 555 (ffi_type *)(&ffitype), NULL \ 556 @}; \ 557 struct struct_align_complex_##name @{ \ 558 char c; \ 559 _Complex type x; \ 560 @}; \ 561 ffi_type ffi_type_complex_##name = @{ \ 562 sizeof(_Complex type), \ 563 offsetof(struct struct_align_complex_##name, x), \ 564 FFI_TYPE_COMPLEX, \ 565 (ffi_type **)ffi_elements_complex_##name \ 566 @} 567 568 /* Define new complex type descriptors using the macro: */ 569 /* ffi_type_complex_sint */ 570 FFI_COMPLEX_TYPEDEF(sint, int, ffi_type_sint); 571 /* ffi_type_complex_uchar */ 572 FFI_COMPLEX_TYPEDEF(uchar, unsigned char, ffi_type_uint8); 573 @end example 574 575 The new type descriptors can then be used like one of the built-in 576 type descriptors in the previous example. 577 578 @node Multiple ABIs 579 @section Multiple ABIs 580 581 A given platform may provide multiple different ABIs at once. For 582 instance, the x86 platform has both @samp{stdcall} and @samp{fastcall} 583 functions. 584 585 @code{libffi} provides some support for this. However, this is 586 necessarily platform-specific. 587 588 @c FIXME: document the platforms 589 590 @node The Closure API 591 @section The Closure API 592 593 @code{libffi} also provides a way to write a generic function -- a 594 function that can accept and decode any combination of arguments. 595 This can be useful when writing an interpreter, or to provide wrappers 596 for arbitrary functions. 597 598 This facility is called the @dfn{closure API}. Closures are not 599 supported on all platforms; you can check the @code{FFI_CLOSURES} 600 define to determine whether they are supported on the current 601 platform. 602 @cindex closures 603 @cindex closure API 604 @findex FFI_CLOSURES 605 606 Because closures work by assembling a tiny function at runtime, they 607 require special allocation on platforms that have a non-executable 608 heap. Memory management for closures is handled by a pair of 609 functions: 610 611 @findex ffi_closure_alloc 612 @defun void *ffi_closure_alloc (size_t @var{size}, void **@var{code}) 613 Allocate a chunk of memory holding @var{size} bytes. This returns a 614 pointer to the writable address, and sets *@var{code} to the 615 corresponding executable address. 616 617 @var{size} should be sufficient to hold a @code{ffi_closure} object. 618 @end defun 619 620 @findex ffi_closure_free 621 @defun void ffi_closure_free (void *@var{writable}) 622 Free memory allocated using @code{ffi_closure_alloc}. The argument is 623 the writable address that was returned. 624 @end defun 625 626 627 Once you have allocated the memory for a closure, you must construct a 628 @code{ffi_cif} describing the function call. Finally you can prepare 629 the closure function: 630 631 @findex ffi_prep_closure_loc 632 @defun ffi_status ffi_prep_closure_loc (ffi_closure *@var{closure}, ffi_cif *@var{cif}, void (*@var{fun}) (ffi_cif *@var{cif}, void *@var{ret}, void **@var{args}, void *@var{user_data}), void *@var{user_data}, void *@var{codeloc}) 633 Prepare a closure function. 634 635 @var{closure} is the address of a @code{ffi_closure} object; this is 636 the writable address returned by @code{ffi_closure_alloc}. 637 638 @var{cif} is the @code{ffi_cif} describing the function parameters. 639 640 @var{user_data} is an arbitrary datum that is passed, uninterpreted, 641 to your closure function. 642 643 @var{codeloc} is the executable address returned by 644 @code{ffi_closure_alloc}. 645 646 @var{fun} is the function which will be called when the closure is 647 invoked. It is called with the arguments: 648 @table @var 649 @item cif 650 The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}. 651 652 @item ret 653 A pointer to the memory used for the function's return value. 654 @var{fun} must fill this, unless the function is declared as returning 655 @code{void}. 656 @c FIXME: is this NULL for void-returning functions? 657 658 @item args 659 A vector of pointers to memory holding the arguments to the function. 660 661 @item user_data 662 The same @var{user_data} that was passed to 663 @code{ffi_prep_closure_loc}. 664 @end table 665 666 @code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything 667 went ok, and something else on error. 668 @c FIXME: what? 669 670 After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc} 671 to the appropriate pointer-to-function type. 672 @end defun 673 674 You may see old code referring to @code{ffi_prep_closure}. This 675 function is deprecated, as it cannot handle the need for separate 676 writable and executable addresses. 677 678 @node Closure Example 679 @section Closure Example 680 681 A trivial example that creates a new @code{puts} by binding 682 @code{fputs} with @code{stdout}. 683 684 @example 685 #include <stdio.h> 686 #include <ffi.h> 687 688 /* Acts like puts with the file given at time of enclosure. */ 689 void puts_binding(ffi_cif *cif, void *ret, void* args[], 690 void *stream) 691 @{ 692 *(ffi_arg *)ret = fputs(*(char **)args[0], (FILE *)stream); 693 @} 694 695 typedef int (*puts_t)(char *); 696 697 int main() 698 @{ 699 ffi_cif cif; 700 ffi_type *args[1]; 701 ffi_closure *closure; 702 703 void *bound_puts; 704 int rc; 705 706 /* Allocate closure and bound_puts */ 707 closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts); 708 709 if (closure) 710 @{ 711 /* Initialize the argument info vectors */ 712 args[0] = &ffi_type_pointer; 713 714 /* Initialize the cif */ 715 if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 716 &ffi_type_sint, args) == FFI_OK) 717 @{ 718 /* Initialize the closure, setting stream to stdout */ 719 if (ffi_prep_closure_loc(closure, &cif, puts_binding, 720 stdout, bound_puts) == FFI_OK) 721 @{ 722 rc = ((puts_t)bound_puts)("Hello World!"); 723 /* rc now holds the result of the call to fputs */ 724 @} 725 @} 726 @} 727 728 /* Deallocate both closure, and bound_puts */ 729 ffi_closure_free(closure); 730 731 return 0; 732 @} 733 734 @end example 735 736 737 @node Missing Features 738 @chapter Missing Features 739 740 @code{libffi} is missing a few features. We welcome patches to add 741 support for these. 742 743 @itemize @bullet 744 @item 745 Variadic closures. 746 747 @item 748 There is no support for bit fields in structures. 749 750 @item 751 The closure API is 752 753 @c FIXME: ... 754 755 @item 756 The ``raw'' API is undocumented. 757 @c argument promotion? 758 @c unions? 759 @c anything else? 760 @end itemize 761 762 Note that variadic support is very new and tested on a relatively 763 small number of platforms. 764 765 @node Index 766 @unnumbered Index 767 768 @printindex cp 769 770 @bye 771