The previous section illustrated an "in" typemap for converting Python objects to C. When Python is extended with C code the Python interpreter needs to be informed about details of the new C functions that have been linked into the executable. In the previous example, you can call:. This is a good thing, since directors and proxies refer to each other and so must be created and destroyed together. It may also introduce problems on platforms that support more than one linking standard e.
While at first glance it appears to be a bit ISA card, it does not have 'fingers' for data transfer on the higher "AT" portion of the bus connector. It uses the bit extension to the ISA bus to provide the user with an additional choice for an IRQ 10 and DMA 0 m channel only found on the bit portion of the edge connector. Otherwise it is functionally identical to the original Sound Blaster Pro.
Packaged Sound Blaster cards were initially marketed and sold into the retail-channel. It was compliant with the MPC Level 2 standard. Eventually this design proved so popular that Creative made a PCI version of this card.
Rich Sorkin was General Manager of the global business during this time, responsible for product planning, product management, marketing and OEM sales. Since existing DOS programs expected to be able to initiate host-controlled ISA DMA for producing sound, backward compatibility with the older Sound Blaster cards for DOS programs required a software driver work-around; since this work-around necessarily depended on the virtual mode of the PC's CPU in order to catch and reroute accesses from the ISA DMA controller to the card itself, it failed for a number of DOS games that either were not fully compatible with this CPU mode or needed so much free conventional memory that they could not be loaded with the driver occupying part of this memory.
The primary advantage of the ViBRA16 was the inclusion of a It offered similar features to the AWE32, but also had a few notable improvements, including support for greater polyphony , although this was a product of 32 extra software-emulated channels.
The main improvements were better compatibility with older SB models, and an improved signal-to-noise ratio. The AWE64 came in two versions: It was cheap due to lack of hardware acceleration. It is full-duplex but at least in MS Windows cannot play back several sources at once. Boards using AudioPCI tech are usually easily identifiable by the board design and the chip size because they all look quite similar.
ISA soundcards had not resampled but switched between different time bases. When the Sound Blaster Live! All members of the SB Live! For game titles, EAX 1. The EMU10K1 provided high-quality voice sample-based synthesizer a. The Gold highlighted many features aimed at music composition; ease-of-use plug-and-play for musicians , realtime loopback-recording of the MIDI-synthesizer with full freedom of Soundfonts, and environmental effects such as reverb, etc.
The mainstream model was the Sound Blaster Live! Later versions of the Live! Creative also released a SoundBlaster Live! Player edition, which is identical to the regular SoundBlaster Live! It is capable of most of the Live! The card's circuit layout is somewhat simpler than that of the Live!
The Audigy was controversially advertised as a bit sound card. In addition, Audigy 2 supported up to 6. It also featured built-in Dolby Digital EX 6.
The Audigy 2 line were the first sound cards to receive THX certification. There were a few slight printed circuit board modifications and 7. Other than a breakout box , it has no distinguishable difference from the Audigy 2 ZS.
The Audigy 4 Pro is not to be confused with the Audigy 4 Value which contains lower quality DACs and does not have golden plated jacks. The Audigy 4 Value is more in line with the Audigy 2 Value series. The Audigy 4 had a shorter life span than its predecessors, due to the short window between it and the next-generation Sound Blaster X-Fi. The computational power of this processor, i. Gaming, Entertainment, and Creation; each enabling a combination of the features of the chipset.
This release also included the bit crystallizer, which is intended to pronounce percussion elements by placing some emphasis on low and high pitched parts of the sound. The X-Fi, at its release, offered some of the most powerful mixing capabilities available, making it a powerful entry-level card for home musicians.
The other big improvement in the X-Fi over the previous Audigy designs was the complete overhaul of the resampling engine on the card. Many hardcore users worked around this by means of resampling their content using high quality software decoders, usually in the form of a plugin in their media player.
Creative completely re-wrote the resampling method used on the X-Fi and dedicated more than half of the power of the DSP to the process; resulting in a very clean resample. Reviews have been generally positive, but pricing and small model differences have raised questions. The Sound BlasterX AE-5 was announced in June , the first discrete sound card made by Creative in five years since the introduction of the Z-series.
The Sound BlasterX series was announced at gamescom The BlasterX Acoustic Engine Lite software comes with preset audio profiles for different game types. There is also an equalizer tab in the software. The Sound BlasterX P5 is an earphone with an inline microphone. Unlike the Sound Blaster E5, it does not have built-in microphones, rechargeable battery and Bluetooth connectivity.
BlasterX Acoustic Engine profiles can be saved onto the device in Windows and used on a Mac computer. It has got 4-pole headphones and microphone audio port. Its headphones amplifier supports headphones with impedances from 16 ohms to ohms. The profiles in the X-Plus Configurator apply equalizer settings tuned for certain games. Sound Blaster cards since conform to Microsoft's PC 99 standard for color-coding the external connectors as follows:. Up until the AWE line in , Creative cards have short text inscriptions on the backplane of the card, indicating which port does what i.
On later cards, the text inscriptions were changed to icons. With the latest cards from Creative, the cards were changed to use numbers as the ports are flexi-jacks and can have different functions assigned to them at run-time i.
Some drivers from the Audigy 2 ZS have been soft-modded by enthusiasts. These can be installed on Creative 's older cards, including Sound Blaster Live! It has been claimed to offer improved sound quality, hardware acceleration of higher EAX versions in games, channel mixing for Audigy 1, and an overall improvement in the card's performance.
Several forum posts across the web have reported favorable results with this technique, excepting Live! Comments on forums from developers of the software mod have said that Live! Later, in , Creative released updated drivers top-to-bottom for the Audigy through Audigy 4 line that put these cards basically at feature parity on a software level. As of , the entire Audigy lineup uses the same driver package.
DSP decoding at the driver level on other cards than Audigy 2 ZS and 4 is still not supported by official drivers, but it works with soft-modded drivers on the other cards with hardware DSP like Audigy 2 6. When Windows Vista was released, there was only a single beta driver for the Creative Audigy series that was usable on the operating system with minimal functionality and frequent instability reported by users.
The encoding will vary depending on the native byte-ordering of the platform i. Similarly, don't try to manually cast a pointer to a new type by simply replacing the type-string. If you need to cast a pointer or change its value, consider writing some helper functions instead.
If you wrap a C structure, it is wrapped by a Python class. This provides a very natural interface. If you print out the value of v in the above example, you will see something like this:. This object is actually a Python instance that has been wrapped around a pointer to the low-level C structure. This instance doesn't actually do anything--it just serves as a proxy. The pointer to the C object can be found in the.
When the structure member is set, the old contents will be released and a new value created. If this is not the behavior you want, you will have to use a typemap described later. If a structure contains arrays, access to those arrays is managed through pointers. For example, consider this:. You can also set the value of an array member using another pointer.
For array assignment, SWIG copies the entire contents of the array starting with the data pointed to by b. In this example, 16 integers would be copied. Like C, SWIG makes no assumptions about bounds checkingif you pass a bad pointer, you may get a segmentation fault or access violation.
When a member of a structure is itself a structure, it is handled as a pointer. For example, suppose you have two structures like this:. In this case, x is a pointer that points to the Foo that is inside b. This is the same value as generated by this C code:. Because the pointer points inside the structure, you can modify the contents and everything works just like you would expect.
Static class members present a special problem for Python. Therefore, SWIG generates wrappers that try to work around some of these issues. To illustrate, suppose you have a class like this:. The first two methods of access are supported in all versions of Python. The last technique is only available in Python Static member variables are currently accessed as global variables.
This means, they are accessed through cvar like this:. Therefore, if you have classes like this. All of the usual Python utility functions work normally:. In Python, there is no detailed distinction like this--specifically, there are only "objects".
There are no pointers, references, arrays, and so forth. Because of this, SWIG unifies all of these types together in the wrapper code. For instance, if you actually had the above functions, it is perfectly legal to do this:. Since the third function spam8 returns a value, newly allocated memory is used to hold the result and a pointer is returned Python will release this memory when the return value is garbage collected.
For example, if you have two functions like this:. Sometimes there are methods that SWIG can't disambiguate.
SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence. For example, consider a class like this:. One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class.
For example, if you had code like this. You can still wrap the operator, but you may have to encapsulate it in a special function. Also, be aware that certain operators don't map cleanly to Python.
For instance, overloaded assignment operators don't map to Python semantics and will be ignored. For example, if you have a file like this,. If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately.
If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation.
Obviously, there is more to template wrapping than shown in this example. Some more complicated examples will appear later. In the previous section, a high-level view of Python wrapping was presented. A key component of this wrapping is that structures and classes are wrapped by Python proxy classes.
This provides a very natural Python interface and allows SWIG to support a number of advanced features such as operator overloading. However, a number of low-level details were omitted. This section provides a brief overview of how the proxy classes work. New in SWIG version 2. The use of Python proxy classes has performance implications that may be unacceptable for a high-performance library.
The new -builtin option instructs SWIG to forego the use of proxy classes, and instead create wrapped types as new built-in Python types.
When this option is used, the following section "Proxy classes" does not apply. Details on the use of the -builtin option are in the Built-in Types section. To summarize those chapters, if you have a class like this. Using these wrappers, SWIG generates a high-level Python proxy class also known as a shadow class like this shown for Python 2.
From a user's point of view, it makes the class work normally:. The fact that the class has been wrapped by a real Python class offers certain advantages. For instance, you can attach new Python methods to the class and you can even inherit from it something not supported by Python built-in types until Python 2.
The -builtin option provides a significant performance improvement in the wrapped code. To understand the difference between proxy classes and built-in types, let's take a look at what a wrapped object looks like under both circumstances. When proxy classes are used, each wrapped object in python is an instance of a pure python class. Did you get all that? So, the python Foo object is composed of three parts:. When -builtin is used, the pure python layer is stripped off.
Each wrapped class is turned into a new python built-in type which inherits from SwigPyObject , and SwigPyObject instances are returned directly from the wrapped methods. For more information about python built-in extensions, please refer to the python documentation:.
Use of the -builtin option implies a couple of limitations: Wrapped types may not be raised as python exceptions. There are workarounds for this. For example, if you wrap this class: This works because the first operand mystr defines a way to add a native string to itself. However, the following will not work:. The above code fails, because the first operand -- a native python string -- doesn't know how to add an instance of MyString to itself.
If you have multiple SWIG modules that share type information more info , the -builtin option requires a bit of extra discipline to ensure that base classes are initialized before derived classes. If you want to wrap another module containing a class that inherits from A , this is how it would look:.
The entire justification for the -builtin option is improved performance. To that end, the best way to squeeze maximum performance out of your wrappers is to use operator overloads. Named method dispatch is slow in python, even when compared to other scripting languages. For example, suppose you have this class: You may write python code like this:. Read about all of the available python slots here: There are two ways to define a python slot function: You may override almost all of these slots.
The hashable type can then for example be added to a Python dict. It is the responsibility of the programmer that's you! Some python slots use a method signature which does not match the signature of SWIG-wrapped methods. For those slots, SWIG will automatically generate a "closure" function to re-marshal the arguments before dispatching to the wrapped method.
Setting the "functype" attribute of the feature enables SWIG to generate the chosen closure function. Although this section refers to proxy objects, everything here also applies when the -builtin option is used. Associated with proxy object, is an ownership flag.
When an object is created by a constructor or returned by value, Python automatically takes ownership of the result. On the other hand, when pointers are returned to Python, there is often no way to know where they came from. Therefore, the ownership is set to zero.
This behavior is especially important for classes that act as containers. For example, if a method returns a pointer to an object that is contained inside another object, you definitely don't want Python to assume ownership and destroy it! Related to containers, ownership issues can arise whenever an object is assigned to a member or global variable.
For example, consider this interface:. When wrapped in Python, careful observation will reveal that ownership changes whenever an object is assigned to a global variable. In this case, C is now holding a reference to the objectyou probably don't want Python to destroy it.
Similarly, this occurs for members. For the most part, memory management issues remain hidden. However, there are occasionally situations where you might have to manually change the ownership of an object. For instance, consider code like this:. In this case, the object n is holding a reference to v internally.
However, SWIG has no way to know that this has occurred. Therefore, Python still thinks that it has ownership of the object. If you're lucky, you will only get a segmentation fault. It is also possible to deal with situations like this using typemaps--an advanced topic discussed later.
SWIG makes every attempt to preserve backwards compatibility with older versions of Python to the extent that it is possible. This new-style class system offers many enhancements including static member functions, properties managed attributes , and class methods.
Details about all of these changes can be found on www. However, if these very same wrappers are imported into an older version of Python, old-style classes are used instead. This dual-nature of the wrapper code means that you can create extension modules with SWIG and those modules will work with all versions of Python ranging from Python Moreover, the wrappers take advantage of Python For the most part, the interface presented to users is the same regardless of what version of Python is used.
The only incompatibility lies in the handling of static member functions. Proxy classes provide a more natural, object-oriented way to access extension classes. Changes have been made to SWIG 1. The director feature is disabled by default. To use directors you must make two changes to the interface file. Without this option no director code will be generated. Directors can also be generated implicitly through inheritance. In the following, class Bar will get a director class that handles the methods one and two but not three:.
For each class that has directors enabled, SWIG generates a new class that derives from both the class in question and a special Swig:: The director classes store a pointer to their underlying Python object and handle various issues related to object ownership. Indeed, this is quite similar to the "this" and "thisown" members of the Python proxy classes.
For simplicity let's ignore the Swig:: By default, a director class extends all virtual methods in the inheritance chain of its base class see the preceding section for how to modify this behavior.
The job of the director methods is to route these method calls to the appropriate place in the inheritance chain. That seamless integration is exactly what the director classes provide, transparently skipping over all the messy extension API glue that binds the two languages together.
In reality, the "appropriate place" is one of only two possibilities: Once this decision is made, the rest is fairly easy.
If the correct implementation is in Python, the Python API is used to call the method of the underlying Python object after which the usual virtual method resolution in Python automatically finds the right implementation. Now how does the director decide which language should handle the method call? The basic rule is to handle the method in Python, unless there's a good reason not to.
The reason for this is simple: Python has the most "extended" implementation of the method. This assertion is guaranteed, since at a minimum the Python proxy class implements the method.
If the method in question has been extended by a class derived from the proxy class, that extended implementation will execute exactly as it should. Now comes the "good reason not to" part. If the director method were to blindly call the Python method again, it would get stuck in an infinite loop. We avoid this situation by adding special code to the C wrapper function that tells the director method to not do this.
The C wrapper function compares the pointer to the Python object that called the wrapper function to the pointer stored by the director. One more point needs to be made about the relationship between director classes and proxy classes. This is exactly what happens without directors and is true even if directors are enabled for the particular class in question.
The reason for this difference is that user-defined subclasses may override or extend methods of the original class, so the director class is needed to route calls to these methods correctly. Memory management issues are slightly more complicated with directors than for proxy classes alone. After calling this method, the. When the director class is deleted it decrements the reference count. Assuming no outstanding references to the Python object remain, the Python object will be destroyed at the same time.
This is a good thing, since directors and proxies refer to each other and so must be created and destroyed together. Destroying one without destroying the other will likely cause your program to segfault. Weak references are only available in Python versions 2.
Here is an example:. In this example, we are assuming that FooContainer will take care of deleting all the Foo pointers it contains at some point. Note that no hard references to the Foo objects remain in Python. By default, the directors ignore exceptions that occur during method calls that are resolved in Python.
The following code should suffice in most cases:. Currently no information about the Python error is stored in the Swig:: DirectorMethodException object, but this will likely change in the future.
If an exception occurs in Python at this point, it would be nice for that exception to find its way back to the original caller. Here is an example of a suitable exception handler:. DirectorException used in this example is actually a base class of Swig:: DirectorMethodException, so it will trap this exception.
Because the Python error state is still set when Swig:: DirectorMethodException is thrown, Python will register the exception as soon as the C wrapper function returns. Enabling directors for a class will generate a new director method for every virtual method in the class' inheritance chain.
This alone can generate a lot of code bloat for large hierarchies. Method arguments that require complex conversions to and from target language types can result in large director methods. Compared to classes that do not use directors, the call routing in the director methods does add some overhead. In particular, at least one dynamic cast and one extra function call occurs per method call from Python. Relative to the speed of Python execution this is probably completely negligible.
This could result in a noticeable overhead in some cases. Typemaps for input and output of most of the basic types from director classes have been written. These are roughly the reverse of the usual input and output typemaps used by the wrapper code.
The typemap operation names are 'directorin', 'directorout', and 'directorargout'. The director code does not currently use any of the other kinds of typemaps. It is not clear at this point which kinds are appropriate and need to be supported. Director typemaps for STL classes are in place, and hence you should be able to use std:: Usually the resulting code is neither thread or reentrant safe.
Hence, the user is advised to avoid returning const references in director methods. For example, the user could modify the method interface to use lvalue return types, wherever possible, for example. If that is not possible, the user should avoid enabling the director feature for reentrant, recursive or threaded member methods that return const references.
If you do nothing but feed SWIG a header file, you will get an interface that mimics the behavior described. However, sometimes this isn't enough to produce a nice module. Certain types of functionality might be missing or the interface to certain functions might be awkward. This section describes some common SWIG features that are used to improve your the interface to an extension module.
Sometimes when you create a module, it is missing certain bits of functionality. For example, if you had a function like this. For example, you might get errors like this:. The problem here is that there is no easy way to construct and manipulate a suitable double  value to use.
To fix this, you can write some extra C helper functions. Admittedly, this is not the most elegant looking approach. However, it works and it wasn't too hard to implement. It is possible to clean this up using Python code, typemaps, and other customization features as covered in later sections.
If writing support code in C isn't enough, it is also possible to write code in Python. This code gets inserted in to the. One use of Python code might be to supply a high-level interface to certain functions. For example, this code now seems to work:. Admittedly, this whole scheme for wrapping the two-dimension array argument is rather ad-hoc. Besides, shouldn't a Python list or a Numeric Python array just work normally?
We'll get to those examples soon enough. For now, think of this example as an illustration of what can be done without having to rely on any of the more advanced customization features. The following shows example usage for Python 2. Prior to SWIG 3. As an alternative to providing a block containing Python code, you can include python code from a file. The code is inserted exactly as in the file, so this avoids any issues with the SWIG preprocessor. It's a good approach if you have a non-trivial chunk of Python code to insert.
To use this feature you specify a filename in double quotes, for example:. Sometimes you may want to replace or modify the wrapper function that SWIG creates in the proxy. Often the proxy function created by SWIG is fine, but you simply want to add code to it without touching the rest of the generated function body. For these cases SWIG provides the pythonprepend and pythonappend features which do exactly as their names suggest. The pythonprepend feature will insert its value at the beginning of the proxy function, and pythonappend will insert code at the end of the proxy, just before the return statement.
Usually the pythonappend and pythonprepend features are safer to use than the shadow feature. Also, from SWIG version 1. In this case, only one of parsed methods is examined for the feature.
One of the more interesting features of SWIG is that it can extend structures and classes with new methods--at least in the Python interface.
Here is a simple example:. For example, if you wanted to overload a Python operator, you might do this:. It does not modify the underlying object in any waythe extensions only show up in the Python interface.
In C, a function often indicates an error by returning a status code a negative number or a NULL pointer perhaps. Here is a simple example of how you might handle that:.
If a library provides some kind of general error handling framework, you can also use that. The following exception types can be used as the first argument. This will call any cleanup code freeing any temp variables and then return from the wrapper function so that the Python interpreter can raise the Python exception. Although SWIG is largely automatic, there are certain types of wrapping problems that require additional user input. Examples include dealing with output parameters, strings, binary data, and arrays.
This chapter discusses the common techniques for solving these problems. A common problem in some C programs is handling parameters passed as simple pointers.
The easiest way to handle these situations is to use the typemaps. Since most primitive Python objects are immutable, it is not possible to perform in-place modification of a Python object passed as a parameter. The most common use of these special typemap rules is to handle functions that return more than one value. For example, sometimes a function returns a result as well as a special error code:.
Be aware that the primary purpose of the typemaps. Writing a function like this. In this case, the functions are as follows:. To wrap this into Python, you need to pass an array pointer as the first argument. A simple way to do this is to use the carrays. For instance, you will be able to do this in Python:.
In fact, there is no bounds checking or safety of any kind just like in C. Because of this, the arrays created by this library are extremely low-level indeed. You can't iterate over them nor can you even query their length. In fact, any valid memory address can be accessed if you want negative indices, indices beyond the end of the array, etc. Needless to say, this approach is not going to suit all applications. On the other hand, this low-level approach is extremely efficient and well suited for applications in which you need to create buffers, package binary data, etc.
When a Python string is passed as a parameter, the C function receives a pointer to the raw data contained in the string. Since Python strings are immutable, it is illegal for your program to change the value. In fact, doing so will probably crash the Python interpreter. If your program modifies the input parameter or uses it to return data, consider using the cstring.
Data is copied into a new Python string and returned. As luck would have it, just such a typemap is already defined. If you need to return binary data, you might use the cstring. There is also an optional Python specific feature that can be used called the python: Some code generation modes are quite different, eg -builtin and -fastproxy , and are unaffected by python: Note that not all default arguments can be converted into a Python equivalent.
This will happen if just one argument cannot be converted into a Python equivalent. This occurs typically when the argument is not fully numeric, such as int This is an advanced topic that assumes familiarity with the Python C API as well as the material in the " Typemaps " chapter.
Before proceeding, it should be stressed that typemaps are not a required part of using SWIGthe default wrapping behavior is enough in most cases.
Typemaps are only used if you want to change some aspect of the primitive C-Python interface or if you want to elevate your guru status. A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from Python to C, you might define a typemap like this:. Typemaps are always associated with some specific aspect of code generation. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values.
In this example, the typemap is applied to all occurrences of the int datatype. You can refine this by supplying an optional parameter name. In this case, the typemap code is only attached to arguments that exactly match int nonnegative. When you define a typemap for int , that typemap applies to int and qualified variations such as const int. In addition, the typemap system follows typedef declarations. When a multi-argument typemap is defined, the arguments are always handled as a single Python object.
This allows the function to be used like this notice how the length parameter is omitted:. The previous section illustrated an "in" typemap for converting Python objects to C. A variety of different typemap methods are defined by the Python module.
For example, to convert a C integer back into a Python object, you might define an "out" typemap like this:. A detailed list of available methods can be found in the " Typemaps " chapter.
However, the best source of typemap information and examples is probably the Python module itself. In fact, all of SWIG's default type handling is defined by typemaps. You can view these typemaps by looking at the files in the SWIG library. Just take into account that in the latest versions of swig 1. The extensive use of macros and other ugly techniques in the latest version produce a very powerful and consistent python typemap library, but at the cost of simplicity and pedagogic value.
To learn how to write a simple or your first typemap, you better take a look at the SWIG library version 1. A full list of variables can be found in the " Typemaps " chapter. This is a list of the most common variables:. When you write a typemap, you usually have to work directly with Python objects. The following functions may prove to be useful. This section includes a few examples of typemaps.
For more examples, you might look at the files " python. A common problem in many C programs is the processing of command line arguments, which are usually passed in an array of NULL terminated strings.
In the example, two different typemaps are used. The "in" typemap is used to receive an input argument and convert it to a C array. Since dynamic memory allocation is used to allocate memory for the array, the "freearg" typemap is used to later release this memory after the execution of the C function. This allows the function to be used from Python as follows:.
Although this works, it's a little awkward to specify the argument count. To fix this, a multi-argument typemap can be defined. This is not very difficult--you only have to make slight modifications to the previous example:.
The typemap code simply fills in the appropriate values from the supplied Python object. With the above typemap in place, you will find it no longer necessary to supply the argument count.
This is automatically set by the typemap code. A common problem in some C programs is that values may be returned in arguments rather than in the return value of a function. The typemap works as follows.
First, a check is made to see if any previous result exists. If so, it is turned into a tuple and the new output value is concatenated to it. Otherwise, the result is returned normally. For the sample function spam , there are three output values--meaning that the function will return a 3-tuple of the results.
As written, the function must accept 4 arguments as input values, last two being pointers to doubles. If these arguments are only used to hold output values and have no meaningful input value , an additional typemap can be written. However, since the argument still has to be set to some meaningful value before calling C, it is set to point to a local variable temp.