{"action":"created","comment":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/26136728","id":26136728,"diff_hunk":"@@ -144,248 +149,554 @@ memory to be passed to the callee and filled in. Allocation of memory\n from Julia like this is generally accomplished by creating an\n uninitialized array and passing a pointer to its data to the C function.\n \n-A prefix ``&`` is used to indicate that a pointer to a scalar argument\n-should be passed instead of the scalar value itself (required for all\n-Fortran function arguments, as noted above). The following\n-example computes a dot product using a BLAS function.\n+Creating C-Compatible Julia Function Pointers\n+---------------------------------------------\n \n-::\n+It is possible to pass Julia functions to native c-functions that accept\n+function pointer arguments. For example, to match c-prototypes of the form::\n \n-    function compute_dot(DX::Vector{Float64}, DY::Vector{Float64})\n-      assert(length(DX) == length(DY))\n-      n = length(DX)\n-      incx = incy = 1\n-      product = ccall( (:ddot_, \"libLAPACK\"),\n-                      Float64,\n-                      (Ptr{Int32}, Ptr{Float64}, Ptr{Int32}, Ptr{Float64}, Ptr{Int32}),\n-                      &n, DX, &incx, DY, &incy)\n-      return product\n+    typedef returntype (*functiontype)(argumenttype,...)\n+\n+The function `cfunction` generates the c-compatible function pointer for\n+a call to a Julia Julia library function.\n+Arguments to ``cfunction`` are as follows:\n+\n+1. A Julia Function\n+\n+2. Return type\n+\n+3. A tuple of input types\n+\n+A classic example is the standard C library ``qsort`` function,\n+declared as::\n+\n+    void qsort(void *base, size_t nmemb, size_t size,\n+               int(*compare)(const void *a, const void *b));\n+\n+The ``base`` argument is a pointer to an array of length ``nmemb``, with elements of\n+``size`` bytes each. ``compare`` is a callback function which takes pointers to two\n+elements ``a`` and ``b`` and returns an integer less/greater than zero if ``a`` should\n+appear before/after ``b`` (or zero if any order is permitted). Now, suppose that we\n+have a 1d array ``A`` of values in Julia that we want to sort using the ``qsort``\n+function (rather than Julia’s built-in ``sort`` function). Before we worry about calling\n+``qsort`` and passing arguments, we need to write a comparison function that works for\n+some arbitrary type T::\n+\n+    function mycompare{T}(a::T, b::T)\n+        return convert(Cint, a < b ? -1 : a > b ? +1 : 0)::Cint\n     end\n \n-The meaning of prefix ``&`` is not quite the same as in C. In\n-particular, any changes to the referenced variables will not be\n-visible in Julia unless the type is mutable (declared via\n-``type``). However, even for immutable types it will not cause any\n-harm for called functions to attempt such modifications (that is,\n-writing through the passed pointers). Moreover, ``&`` may be used with\n-any expression, such as ``&0`` or ``&f(x)``.\n+Notice that we have to be careful about the return type: ``qsort`` expects a function\n+returning a C ``int``, so we must be sure to return ``Cint`` via a call to ``convert``\n+and a ``typeassert``.\n+\n+In order to pass this function to C, we obtain its address using the function ``cfunction``::\n+\n+    const mycompare_c = cfunction(mycompare, Cint, (Ref{Cdouble}, Ref{Cdouble}))\n+\n+``cfunction`` accepts three arguments: the Julia function (``mycompare``), the return\n+type (``Cint``), and a tuple of the argument types, in this case to sort an array of\n+``Cdouble`` (Float64) elements.\n+\n+The final call to ``qsort`` looks like this::\n+\n+    A = [1.3, -2.7, 4.4, 3.1]\n+    ccall(:qsort, Void, (Ptr{Cdouble}, Csize_t, Csize_t, Ptr{Void}),\n+          A, length(A), sizeof(eltype(A)), mycompare_c)\n+\n+After this executes, ``A`` is changed to the sorted array ``[-2.7, 1.3, 3.1, 4.4]``.\n+Note that Julia knows how to convert an array into a ``Ptr{Cdouble}``, how to compute\n+the size of a type in bytes (identical to C’s ``sizeof`` operator), and so on.\n+For fun, try inserting a ``println(\"mycompare($a,$b)\")`` line into ``mycompare``, which\n+will allow you to see the comparisons that ``qsort`` is performing (and to verify that\n+it is really calling the Julia function that you passed to it).\n \n-Currently, it is not possible to reliably pass structs and other non-primitive\n-types by *value* from Julia to/from C libraries. However, *pointers*\n-to structs can be passed.  The simplest case is that of C functions\n-that generate and use *opaque* pointers to struct types, which can be\n-passed to/from Julia as ``Ptr{Void}`` (or any other ``Ptr``\n-type). Memory allocation and deallocation of such objects must be\n-handled by calls to the appropriate cleanup routines in the libraries\n-being used, just like in any C program.  A more complicated approach\n-is to declare a composite type in Julia that mirrors a C struct, which\n-allows the structure fields to be directly accessed in Julia.  Given a\n-Julia variable ``x`` of that type, a pointer can be passed as ``&x``\n-to a C function expecting a pointer to the corresponding struct.  If\n-the Julia type ``T`` is ``immutable``, then a Julia ``Array{T}`` is\n-stored in memory identically to a C array of the corresponding struct,\n-and can be passed to a C program expecting such an array pointer.\n-\n-Note that no C header files are used anywhere in the process: you are\n-responsible for making sure that your Julia types and call signatures\n-accurately reflect those in the C header file.  (The `Clang package\n-<https://github.com/ihnorton/Clang.jl>` can be used to generate Julia\n-code from a C header file.)\n \n Mapping C Types to Julia\n ------------------------\n \n+It is critical to exactly match the declared C type with its declaration\n+in Julia. Inconsistencies can cause code that works correctly on one system\n+to fail or produce indeterminate results on a different system.\n+\n+Note that no C header files are used anywhere in the process of calling C\n+functions: you are responsible for making sure that your Julia types and\n+call signatures accurately reflect those in the C header file. (The `Clang\n+package` <https://github.com/ihnorton/Clang.jl> can be used to auto-generate\n+Julia code from a C header file.)\n+\n+Auto-conversion:\n+~~~~~~~~~~~~~~~~\n+\n Julia automatically inserts calls to the ``convert`` function to convert\n each argument to the specified type. For example, the following call::\n \n-    ccall( (:foo, \"libfoo\"), Void, (Int32, Float64),\n-          x, y)\n+    ccall((:foo, \"libfoo\"), Void, (Int32, Float64), x, y)\n \n will behave as if the following were written::\n \n-    ccall( (:foo, \"libfoo\"), Void, (Int32, Float64),\n-          convert(Int32, x), convert(Float64, y))\n+    ccall((:foo, \"libfoo\"), Void, (Int32, Float64),\n+          Base.cconvert(Int32, Base.cconvert_gcroot(Int32, x)),\n+          Base.cconvert(Float64, Base.cconvert_gcroot(Float64, y)))\n \n-When a scalar value is passed with ``&`` as an argument of type\n-``Ptr{T}``, the value will first be converted to type ``T``.\n+Note that the primary fall-back method for ``cconvert`` is::\n \n-Array conversions\n-~~~~~~~~~~~~~~~~~\n+    cconvert(T,x) = convert(T, x)\n+\n+and the primary fallback method for ``cconvert_gcroot`` is::\n+\n+    cconvert_gcroot(T,x) = x\n+\n+Type Correspondences:\n+~~~~~~~~~~~~~~~~~~~~~\n+\n+First, a review of some relevant Julia type terminology:\n \n-When an array is passed to C as a ``Ptr{T}`` argument, it is\n-never converted: Julia simply checks that the element type of the\n-array matches ``T``, and the address of the first element is passed.\n-This is done in order to avoid copying arrays unnecessarily.\n+.. rst-class:: text-wrap\n \n-Therefore, if an ``Array`` contains data in the wrong format, it will\n-have to be explicitly converted using a call such as ``Vector{Int32}(a)``.\n+==============================  ==============================  ======================================================\n+Syntax / Keyword                Example                         Description\n+==============================  ==============================  ======================================================\n+``type``                        ``ASCIIString``                 \"Leaf Type\" :: A group of related data that includes\n+                                                                a type-tag, is managed by the Julia GC, and\n+                                                                is defined by object-identity.\n+                                                                The type parameters of a leaf type must be fully defined\n+                                                                (no `TypeVars` are allowed)\n+                                                                in order for the instance to be constructed.\n \n-To pass an array ``A`` as a pointer of a different type *without*\n-converting the data beforehand (for example, to pass a ``Float64`` array\n-to a function that operates on uninterpreted bytes), you can either\n-declare the argument as ``Ptr{Void}`` or you can explicitly call\n-``convert(Ptr{T}, pointer(A))``.\n+``abstract``                    ``Any``,                        \"Super Type\" :: A super-type (not a leaf-type)\n+                                ``AbstractArray{T,N}``,         that cannot be instantiated, but can be used to\n+                                ``Complex{T}``                  describe a group of types\n \n+``{T}``                         ``Vector{Int}``                 \"Type Parameter\" :: A specialization of a type\n+                                                                (typically used to dispatch or storage optimization)\n+\n+                                                                \"TypeVar\" :: The ``T`` in the type parameter declaration\n+                                                                is referred to as a TypeVar (short for type variable)\n+\n+``bitstype``                    ``Int``,                        \"Bits Type\" :: A type with no fields, but a size. It\n+                                ``Float64``                     is stored and defined by-value\n+\n+``immutable``                   ``Pair{String,String}``         \"Immutable\" :: A type with all fields defined to be\n+                                                                constant. It is defined by-value. And may be stored\n+                                                                with a type-tag.\n+\n+                                ``Complex128`` (`isbits`)       \"Is-Bits\" :: A ``bitstype``, or an ``immutable`` type\n+                                                                where all fields are other ``isbits`` types. It is\n+                                                                defined by-value, and is stored without a type-tag\n+\n+``type ...; end``               ``nothing``                     \"Singleton\" :: a Leaf Type or Immutable with no fields\n+\n+``(...)`` or ``tuple(...)```    ``(1,2,3)``                     \"Tuple\" :: an immutable data-structure similar to an\n+                                                                anonymous immutable type, or a constant array. it's\n+                                                                storage semantics are TBD.\n+\n+``typealias``                   Not applicable here             Type aliases, and other similar mechanisms of\n+                                                                doing type indirection, are resolved to their base\n+                                                                type (this includes assigning a type to another name,\n+                                                                or getting the type out of a function call)\n+==============================  ==============================  ======================================================\n+\n+Bits Types:\n+~~~~~~~~~~~\n+\n+There are several special types to be aware of, as no other type can be defined to behave the same:\n+\n+:Float32: Exactly corresponds to the ``float`` type in C (or ``REAL*4`` in Fortran)\n+:Float64: Exactly corresponds to the ``double`` type in C (or ``REAL*8`` in Fortran)\n+:Complex64: Exactly corresponds to the ``complex float`` type in C (or ``COMPLEX*8`` in Fortran)\n+:Complex128: Exactly corresponds to the ``complex double`` type in C (or ``COMPLEX*16`` in Fortran)\n+:Signed: Exactly corresponds to the ``signed`` type annotation in C (or any ``INTEGER`` type in Fortran). Any Julia type that is not a subtype of ``Signed`` is assumed to be unsigned\n+:Ref{T}: Behaves like a ``Ptr{T}`` that owns it's memory\n+:Array{T,N}:\n+    When an array is passed to C as a ``Ptr{T}`` argument, it is\n+    not reinterpret-cast: Julia requires that the element type of the\n+    array matches ``T``, and then address of the first element is passed.\n+\n+    Therefore, if an ``Array`` contains data in the wrong format, it will\n+    have to be explicitly converted using a call such as ``int32(a)``.\n+\n+    To pass an array ``A`` as a pointer of a different type *without*\n+    converting the data beforehand (for example, to pass a ``Float64`` array\n+    to a function that operates on uninterpreted bytes), you can either\n+    declare the argument as ``Ptr{Void}`` or you can explicitly call\n+    ``pointer(A)``.\n+\n+    If an array of eltype ``Ptr{T}`` is passed as a ``Ptr{Ptr{T}}`` argument, the Julia base library\n+    `cconvert_gcroot` function will attempt to first make a null-terminated copy of the array with\n+    each element replaced by it's ``cconvert`` version. This allows, for example, passing an ``argv``\n+    pointer array of type ``Vector{ByteString}`` to an argument of type ``Ptr{Ptr{Cchar}}``.\n \n-Type correspondences\n-~~~~~~~~~~~~~~~~~~~~\n \n On all systems we currently support, basic C/C++ value types may be\n translated to Julia types as follows. Every C type also has a corresponding\n Julia type with the same name, prefixed by C. This can help for writing portable code (and remembering that an int in C is not the same as an Int in Julia).\n \n-**System-independent:**\n-\n-+------------------------+-------------------+--------------------------------+\n-| ``unsigned char``      | ``Cuchar``        | ``UInt8``                      |\n-+------------------------+-------------------+--------------------------------+\n-| ``short``              | ``Cshort``        | ``Int16``                      |\n-+------------------------+-------------------+--------------------------------+\n-| ``unsigned short``     | ``Cushort``       | ``UInt16``                     |\n-+------------------------+-------------------+--------------------------------+\n-| ``int``                | ``Cint``          | ``Int32``                      |\n-+------------------------+-------------------+--------------------------------+\n-| ``unsigned int``       | ``Cuint``         | ``UInt32``                     |\n-+------------------------+-------------------+--------------------------------+\n-| ``long long``          | ``Clonglong``     | ``Int64``                      |\n-+------------------------+-------------------+--------------------------------+\n-| ``unsigned long long`` | ``Culonglong``    | ``UInt64``                     |\n-+------------------------+-------------------+--------------------------------+\n-| ``intmax_t``           | ``Cintmax_t``     | ``Int64``                      |\n-+------------------------+-------------------+--------------------------------+\n-| ``uintmax_t``          | ``Cuintmax_t``    | ``UInt64``                     |\n-+------------------------+-------------------+--------------------------------+\n-| ``float``              | ``Cfloat``        | ``Float32``                    |\n-+------------------------+-------------------+--------------------------------+\n-| ``double``             | ``Cdouble``       | ``Float64``                    |\n-+------------------------+-------------------+--------------------------------+\n-| ``ptrdiff_t``          | ``Cptrdiff_t``    | ``Int``                        |\n-+------------------------+-------------------+--------------------------------+\n-| ``ssize_t``            | ``Cssize_t``      | ``Int``                        |\n-+------------------------+-------------------+--------------------------------+\n-| ``size_t``             | ``Csize_t``       | ``UInt``                       |\n-+------------------------+-------------------+--------------------------------+\n-| ``void``               |                   | ``Void``                       |\n-+------------------------+-------------------+--------------------------------+\n-| ``void*``              |                   | ``Ptr{Void}``                  |\n-+------------------------+-------------------+--------------------------------+\n-| ``char*`` (or ``char[]``, e.g. a string)   | ``Ptr{UInt8}``                 |\n-+------------------------+-------------------+--------------------------------+\n-| ``char**`` (or ``*char[]``)                | ``Ptr{Ptr{UInt8}}``            |\n-+------------------------+-------------------+--------------------------------+\n-| ``struct T*`` (where T represents an       | ``Ptr{T}`` (call using         |\n-| appropriately defined bits type)           | &variable_name in the          |\n-|                                            | parameter list)                |\n-+------------------------+-------------------+--------------------------------+\n-| ``jl_value_t*`` (any Julia Type)           | ``Ptr{Any}``                   |\n-+------------------------+-------------------+--------------------------------+\n-\n-Julia's ``Char`` type is 32 bits, which is not the same as the wide\n-character type (``wchar_t`` or ``wint_t``) on all platforms.\n-\n-A C function declared to return ``void`` will give ``nothing`` in Julia.\n+**System Independent:**\n+\n+.. rst-class:: text-wrap\n+\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| C name                            | Fortran name    | Standard Julia Alias | Julia Base Type                   |\n++===================================+=================+======================+===================================+\n+| ``unsigned char``                 | ``CHARACTER``   | ``Cuchar``           | ``UInt8``                         |\n+|                                   |                 |                      |                                   |\n+| ``bool`` (`C++`)                  |                 |                      |                                   |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``short``                         | ``INTEGER*2``   | ``Cshort``           | ``Int16``                         |\n+|                                   |                 |                      |                                   |\n+|                                   | ``LOGICAL*2``   |                      |                                   |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``unsigned short``                |                 | ``Cushort``          | ``UInt16``                        |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``int``                           | ``INTEGER*4``   | ``Cint``             | ``Int32``                         |\n+|                                   |                 |                      |                                   |\n+| ``BOOL`` (`C`, typical)           | ``LOGICAL*4``   |                      |                                   |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``unsigned int``                  |                 | ``Cuint``            | ``UInt32``                        |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``long long``                     | ``INTEGER*8``   | ``Clonglong``        | ``Int64``                         |\n+|                                   |                 |                      |                                   |\n+|                                   | ``LOGICAL*8``   |                      |                                   |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``unsigned long long``            |                 | ``Culonglong``       | ``UInt64``                        |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``intmax_t``                      |                 | ``Cintmax_t``        | ``Int64``                         |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``uintmax_t``                     |                 | ``Cuintmax_t``       | ``UInt64``                        |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``float``                         | ``REAL*4i``     | ``Cfloat``           | ``Float32``                       |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``double``                        | ``REAL*8``      | ``Cdouble``          | ``Float64``                       |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``complex float``                 | ``COMPLEX*8``   | ``Complex64``        | ``Complex{Float32}``              |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``complex double``                | ``COMPLEX*16``  | ``Complex128``       | ``Complex{Float64}``              |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``ptrdiff_t``                     |                 | ``Cptrdiff_t``       | ``Int``                           |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``ssize_t``                       |                 | ``Cssize_t``         | ``Int``                           |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``size_t``                        |                 | ``Csize_t``          | ``UInt``                          |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``void``                          |                 |                      | ``Void``                          |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``void*``                         |                 |                      | ``Ptr{Void}``                     |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``T*`` (where T represents an     |                 |                      | ``Ref{T}``                        |\n+| appropriately defined type)       |                 |                      |                                   |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``char*``                         | ``CHARACTER*N`` |                      | ``Ptr{UInt8}``                    |\n+| (or ``char[]``, e.g. a string)    |                 |                      |                                   |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``char**`` (or ``*char[]``)       |                 |                      | ``Ptr{Ptr{UInt8}}``               |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``jl_value_t*``                   |                 |                      | ``Any``                           |\n+| (any Julia Type)                  |                 |                      |                                   |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``jl_value_t**``                  |                 |                      | ``Ref{Any}``                      |\n+| (a reference to a Julia Type)     |                 |                      |                                   |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``va_arg``                        |                 |                      | Not supported                     |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n+| ``...``                           |                 |                      | ```T...``` (where ``T``           |\n+| (variadic function specification) |                 |                      | is one of the above types,        |\n+|                                   |                 |                      | variadic functions of different   |\n+|                                   |                 |                      | argument types are not supported) |\n++-----------------------------------+-----------------+----------------------+-----------------------------------+\n \n **System-dependent:**\n \n-======================  ==============  =======\n-``char``                ``Cchar``       ``Int8`` (x86, x86_64)\n+======================  ======================  =======\n+C name                  Standard Julia Alias    Julia Base Type\n+======================  ======================  =======\n+``char``                ``Cchar``               ``Int8`` (x86, x86_64)\n \n-                                        ``UInt8`` (powerpc, arm)\n-``long``                ``Clong``       ``Int`` (UNIX)\n+                                                ``UInt8`` (powerpc, arm)\n \n-                                        ``Int32`` (Windows)\n-``unsigned long``       ``Culong``      ``UInt`` (UNIX)\n+``long``                ``Clong``               ``Int`` (UNIX)\n \n-                                        ``UInt32`` (Windows)\n-``wchar_t``             ``Cwchar_t``    ``Int32`` (UNIX)\n+                                                ``Int32`` (Windows)\n \n-                                        ``UInt16`` (Windows)\n-======================  ==============  =======\n+``unsigned long``       ``Culong``              ``UInt`` (UNIX)\n \n-For string arguments (``char*``) the Julia type should be ``Ptr{UInt8}``,\n-not ``ASCIIString``. C functions that take an argument of the type ``char**``\n-can be called by using a ``Ptr{Ptr{UInt8}}`` type within Julia. For example,\n-C functions of the form::\n+                                                ``UInt32`` (Windows)\n \n-    int main(int argc, char **argv);\n+``wchar_t``             ``Cwchar_t``            ``Int32`` (UNIX)\n \n-can be called via the following Julia code::\n+                                                ``UInt16`` (Windows)\n+======================  ======================  =======\n \n-    argv = [ \"a.out\", \"arg1\", \"arg2\" ]\n-    ccall(:main, Int32, (Int32, Ptr{Ptr{UInt8}}), length(argv), argv)\n+`Remember`: when calling a Fortran function, all inputs must be passed by reference, so all type correspondences\n+above should contain an additional ``Ptr{..}`` or ``Ref{..}`` wrapper around their type specification.\n+\n+`Warning`: For string arguments (``char*``) the Julia type should be ``Ptr{Cchar}``,\n+not ``ASCIIString``. Similarly, for array arguments (``T[]`` or ``T*``), the Julia\n+type should again be ``Ptr{T}``, not ``Vector{T}``.\n+\n+`Warning`: Julia's ``Char`` type is 32 bits, which is not the same as the wide\n+character type (``wchar_t`` or ``wint_t``) on all platforms.\n \n-For ``wchar_t*`` arguments, the Julia type should be ``Ptr{Wchar_t}``,\n+`Note`: For ``wchar_t*`` arguments, the Julia type should be ``Ptr{Wchar_t}``,\n and data can be converted to/from ordinary Julia strings by the\n ``wstring(s)`` function (equivalent to either ``utf16(s)`` or ``utf32(s)``\n depending upon the width of ``Cwchar_t``.    Note also that ASCII, UTF-8,\n UTF-16, and UTF-32 string data in Julia is internally NUL-terminated, so\n it can be passed to C functions expecting NUL-terminated data without making\n a copy.\n+`Note`: C functions that take an argument of the type ``char**`` can be called by using\n+a ``Ptr{Ptr{UInt8}}`` type within Julia. For example,\n+C functions of the form::\n \n-Accessing Data through a Pointer\n---------------------------------\n-The following methods are described as \"unsafe\" because they can cause Julia\n-to terminate abruptly or corrupt arbitrary process memory due to a bad pointer\n-or type declaration.\n+    int main(int argc, char **argv);\n \n-Given a ``Ptr{T}``, the contents of type ``T`` can generally be copied from\n-the referenced memory into a Julia object using ``unsafe_load(ptr, [index])``. The\n-index argument is optional (default is 1), and performs 1-based indexing. This\n-function is intentionally similar to the behavior of ``getindex()`` and ``setindex!()``\n-(e.g. ``[]`` access syntax).\n+can be called via the following Julia code::\n \n-The return value will be a new object initialized\n-to contain a copy of the contents of the referenced memory. The referenced\n-memory can safely be freed or released.\n+    argv = [ \"a.out\", \"arg1\", \"arg2\" ]\n+    ccall(:main, Int32, (Int32, Ptr{Ptr{UInt8}}), length(argv), argv)\n \n-If ``T`` is ``Any``, then the memory is assumed to contain a reference to\n-a Julia object (a ``jl_value_t*``), the result will be a reference to this object,\n-and the object will not be copied. You must be careful in this case to ensure\n-that the object was always visible to the garbage collector (pointers do not\n-count, but the new reference does) to ensure the memory is not prematurely freed.\n-Note that if the object was not originally allocated by Julia, the new object\n-will never be finalized by Julia's garbage collector.  If the ``Ptr`` itself\n-is actually a ``jl_value_t*``, it can be converted back to a Julia object\n-reference by ``unsafe_pointer_to_objref(ptr)``.  (Julia values ``v``\n-can be converted to ``jl_value_t*`` pointers, as ``Ptr{Void}``, by calling\n-``pointer_from_objref(v)``.)\n+`Note`: A C function declared to return ``Void`` will return the value ``nothing`` in Julia.\n \n-The reverse operation (writing data to a Ptr{T}), can be performed using\n-``unsafe_store!(ptr, value, [index])``.  Currently, this is only supported\n-for bitstypes or other pointer-free (``isbits``) immutable types.\n+Struct Type correspondences\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~\n \n-Any operation that throws an error is probably currently unimplemented\n-and should be posted as a bug so that it can be resolved.\n+Composite types, aka ``struct`` in C or ``STRUCTURE`` / ``RECORD`` in Fortran),\n+can be mirrored in Julia by creating a ``type`` or ``immutable``\n+definition with the same field layout.\n \n-If the pointer of interest is a plain-data array (bitstype or immutable), the\n-function ``pointer_to_array(ptr,dims,[own])`` may be more useful. The final\n-parameter should be true if Julia should \"take ownership\" of the underlying\n-buffer and call ``free(ptr)`` when the returned ``Array`` object is finalized.\n-If the ``own`` parameter is omitted or false, the caller must ensure the\n-buffer remains in existence until all access is complete.\n+When used recursively, ``isbits`` types are stored inline.\n+All other types are stored as a pointer to the data.\n+When mirroring a struct used by-value inside another struct in C,\n+it is imperative that you do not attempt to manually copy the fields over,\n+as this will not preserve the correct field alignment.\n+Instead, declare an immutable isbits type and use that instead.\n+Unnamed structs are not possible in the translation to Julia.\n \n-Arithmetic on the ``Ptr`` type in Julia (e.g. using ``+``) does not behave the\n-same as C's pointer arithmetic. Adding an integer to a ``Ptr`` in Julia always\n-moves the pointer by some number of *bytes*, not elements. This way, the\n-address values obtained from pointer arithmetic do not depend on the\n-element types of pointers.\n+Packed structs and union declarations are not supported by Julia.\n+\n+You can get a near approximation of a ``union`` if you know, a priori,\n+the field that will have the greatest size (potentially including padding).\n+When translating your fields to Julia, declare the Julia field to be only\n+of that type.\n+\n+Arrays of parameters must be expanded manually, currently\n+(either inline, or in an immutable helper-type). For example::\n+\n+    in C:\n+    struct B {\n+        int A[3];\n+    };\n+    b_a_2 = B.A[2];\n+\n+    in Julia:\n+    immutable B_A\n+        A_1::Cint\n+        A_2::Cint\n+        A_3::Cint\n+    end\n+    type B\n+        A::B_A\n+    end\n+    b_a_2 = B.A.(2)\n+\n+Arrays of unknown size are not supported.\n+\n+In the future, some of these restrictions may be reduced or eliminated.\n+\n+Memory Ownership:\n+~~~~~~~~~~~~~~~~~\n+\n+**malloc/free**\n+\n+Memory allocation and deallocation of such objects must be\n+handled by calls to the appropriate cleanup routines in the libraries\n+being used, just like in any C program. Do not try to free an object\n+received from a C library with `c_free` in Julia, as this may result\n+in the ``free`` function being called via the wrong `libc` library and\n+cause Julia to crash. The reverse (passing an object allocated in Julia\n+to be freed by an external library) is equally invalid.\n+\n+**Ptr{T} vs. Array{T} vs. Ref{T} vs. T**\n+\n+The choice of type-wrapper declaration strongly depends on who allocated the memory,\n+and the declared type.\n+In general, use ``T`` if the memory is intended to be allocated in\n+(and managed by) Julia (with type-tag).\n+Use ``Ptr{T}`` if the memory is expected to be populated by ``C`` (without type-tag).\n+Use ``Ref{T}`` if you have an ``isbits`` type,\n+but you want to turn it into a pointer to a struct in another struct definition.\n+\n+See issue #2818 for some work that needs to be done to simplify this so that Julia\n+types can be used to recursively mirror c-style structs,\n+without requiring as much manual management of the ``Ptr`` conversions.\n+After #2818 is implemented, it will be true that an `Vector{T}` will be equivalent to\n+an `Ptr{Ptr{T}}`. That is currently not true, and the conversion must be explicitly.","path":"doc/manual/calling-c-and-fortran-code.rst","position":625,"original_position":625,"commit_id":"22490c1a6aaa6a12b60bd64554844de5034d153e","original_commit_id":"22490c1a6aaa6a12b60bd64554844de5034d153e","user":{"login":"stevengj","id":2913679,"avatar_url":"https://avatars.githubusercontent.com/u/2913679?v=3","gravatar_id":"","url":"https://api.github.com/users/stevengj","html_url":"https://github.com/stevengj","followers_url":"https://api.github.com/users/stevengj/followers","following_url":"https://api.github.com/users/stevengj/following{/other_user}","gists_url":"https://api.github.com/users/stevengj/gists{/gist_id}","starred_url":"https://api.github.com/users/stevengj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stevengj/subscriptions","organizations_url":"https://api.github.com/users/stevengj/orgs","repos_url":"https://api.github.com/users/stevengj/repos","events_url":"https://api.github.com/users/stevengj/events{/privacy}","received_events_url":"https://api.github.com/users/stevengj/received_events","type":"User","site_admin":false},"body":"must be performed explicitly.","created_at":"2015-03-10T16:15:03Z","updated_at":"2015-03-10T16:15:03Z","html_url":"https://github.com/JuliaLang/julia/pull/7906#discussion_r26136728","pull_request_url":"https://api.github.com/repos/JuliaLang/julia/pulls/7906","_links":{"self":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/comments/26136728"},"html":{"href":"https://github.com/JuliaLang/julia/pull/7906#discussion_r26136728"},"pull_request":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/7906"}}},"pull_request":{"url":"https://api.github.com/repos/JuliaLang/julia/pulls/7906","id":19503033,"html_url":"https://github.com/JuliaLang/julia/pull/7906","diff_url":"https://github.com/JuliaLang/julia/pull/7906.diff","patch_url":"https://github.com/JuliaLang/julia/pull/7906.patch","issue_url":"https://api.github.com/repos/JuliaLang/julia/issues/7906","number":7906,"state":"closed","locked":false,"title":"Make by-value struct passing work properly","user":{"login":"vtjnash","id":330950,"avatar_url":"https://avatars.githubusercontent.com/u/330950?v=3","gravatar_id":"","url":"https://api.github.com/users/vtjnash","html_url":"https://github.com/vtjnash","followers_url":"https://api.github.com/users/vtjnash/followers","following_url":"https://api.github.com/users/vtjnash/following{/other_user}","gists_url":"https://api.github.com/users/vtjnash/gists{/gist_id}","starred_url":"https://api.github.com/users/vtjnash/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vtjnash/subscriptions","organizations_url":"https://api.github.com/users/vtjnash/orgs","repos_url":"https://api.github.com/users/vtjnash/repos","events_url":"https://api.github.com/users/vtjnash/events{/privacy}","received_events_url":"https://api.github.com/users/vtjnash/received_events","type":"User","site_admin":false},"body":"this is ~~a first cut at~~ (done) ~~rebasing #3466 onto master~~ (also done) ready-to-merge patch to improve ccall/cfunction compatibility. @Keno let me know if you see anything that looks wrong.\r\n\r\n - [x] linux 32 (http://www.uclibc.org/docs/psABI-i386.pdf)\r\n - [x] linux 64 (http://www.uclibc.org/docs/psABI-x86_64.pdf)\r\n - [x] mac 64 (same as linux 64)\r\n - [x] win 32 (https://msdn.microsoft.com/en-us/library/984x0h58.aspx)\r\n - [x] win 64 (https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx)\r\n\r\nTo keep track of issues (from comments) from the previous PR:\r\n\r\n - [x] Need to add link to LDC\r\n - [x] ~~Need to figure out what to do with fixed-size arrays.~~ (will be done later)\r\n - [x] merge the Mutable module from Gtk into base (#9986)\r\n - [x] implement https://gist.github.com/vtjnash/7296634 ~~(only cfunction updates remain)~~\r\n - [x] build libccalltest on travis\r\n - [x] update documentation on ccall/cfunction in manual\r\n - [x] add documentation for Ref type to stdlib\r\n - [x] more tests for cfunction/ccall/Ref interactions\r\n - [x] use unsafe_load in cfunction when receiving isbits types\r\n - [x] update docs again. add docs for cconvert / unsafe_convert\r\n - [x] add notes to NEWS and email to julia-users list\r\n\r\nfuture work:\r\n - [ ] calling conventions for cfunction\r\n - [x] #2818 (types as c-structs)\r\n - [ ] emit cfunction stubs for any `jl_apply_generic` call (possible sketch of implementation : https://gist.github.com/vtjnash/019b4d5d63b64a772a31)\r\n - [ ] more completely use tuples to emulate more stuff, like fixed size arrays\r\n\r\n~~NOTE: please DO NOT merge this until the cfunction API changes are finalized. (i don't want to need to update Gtk.jl twice)~~","created_at":"2014-08-08T00:13:59Z","updated_at":"2015-03-10T16:15:03Z","closed_at":"2015-03-10T02:22:00Z","merged_at":"2015-03-10T02:22:00Z","merge_commit_sha":"3adfb6266a5efbf8c40dbb269279e369fc9faff5","assignee":null,"milestone":{"url":"https://api.github.com/repos/JuliaLang/julia/milestones/11","html_url":"https://github.com/JuliaLang/julia/milestones/0.4","labels_url":"https://api.github.com/repos/JuliaLang/julia/milestones/11/labels","id":748886,"number":11,"title":"0.4","description":"For tracking release-defining items for 0.4: important new features, breaking changes, and blocking bugs.\r\n\r\nAfter a brief period for deciding scope, adding issues to this milestone is not allowed. Once the items in this milestone are done, 0.4 will enter its stabilizing period and a release candidate can be made soon after.","creator":{"login":"JeffBezanson","id":744556,"avatar_url":"https://avatars.githubusercontent.com/u/744556?v=3","gravatar_id":"","url":"https://api.github.com/users/JeffBezanson","html_url":"https://github.com/JeffBezanson","followers_url":"https://api.github.com/users/JeffBezanson/followers","following_url":"https://api.github.com/users/JeffBezanson/following{/other_user}","gists_url":"https://api.github.com/users/JeffBezanson/gists{/gist_id}","starred_url":"https://api.github.com/users/JeffBezanson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JeffBezanson/subscriptions","organizations_url":"https://api.github.com/users/JeffBezanson/orgs","repos_url":"https://api.github.com/users/JeffBezanson/repos","events_url":"https://api.github.com/users/JeffBezanson/events{/privacy}","received_events_url":"https://api.github.com/users/JeffBezanson/received_events","type":"User","site_admin":false},"open_issues":21,"closed_issues":21,"state":"open","created_at":"2014-08-10T18:13:46Z","updated_at":"2015-03-10T12:48:21Z","due_on":"2015-01-30T05:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/JuliaLang/julia/pulls/7906/commits","review_comments_url":"https://api.github.com/repos/JuliaLang/julia/pulls/7906/comments","review_comment_url":"https://api.github.com/repos/JuliaLang/julia/pulls/comments{/number}","comments_url":"https://api.github.com/repos/JuliaLang/julia/issues/7906/comments","statuses_url":"https://api.github.com/repos/JuliaLang/julia/statuses/22490c1a6aaa6a12b60bd64554844de5034d153e","head":{"label":"JuliaLang:jn/ccall3","ref":"jn/ccall3","sha":"22490c1a6aaa6a12b60bd64554844de5034d153e","user":{"login":"JuliaLang","id":743164,"avatar_url":"https://avatars.githubusercontent.com/u/743164?v=3","gravatar_id":"","url":"https://api.github.com/users/JuliaLang","html_url":"https://github.com/JuliaLang","followers_url":"https://api.github.com/users/JuliaLang/followers","following_url":"https://api.github.com/users/JuliaLang/following{/other_user}","gists_url":"https://api.github.com/users/JuliaLang/gists{/gist_id}","starred_url":"https://api.github.com/users/JuliaLang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JuliaLang/subscriptions","organizations_url":"https://api.github.com/users/JuliaLang/orgs","repos_url":"https://api.github.com/users/JuliaLang/repos","events_url":"https://api.github.com/users/JuliaLang/events{/privacy}","received_events_url":"https://api.github.com/users/JuliaLang/received_events","type":"Organization","site_admin":false},"repo":{"id":1644196,"name":"julia","full_name":"JuliaLang/julia","owner":{"login":"JuliaLang","id":743164,"avatar_url":"https://avatars.githubusercontent.com/u/743164?v=3","gravatar_id":"","url":"https://api.github.com/users/JuliaLang","html_url":"https://github.com/JuliaLang","followers_url":"https://api.github.com/users/JuliaLang/followers","following_url":"https://api.github.com/users/JuliaLang/following{/other_user}","gists_url":"https://api.github.com/users/JuliaLang/gists{/gist_id}","starred_url":"https://api.github.com/users/JuliaLang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JuliaLang/subscriptions","organizations_url":"https://api.github.com/users/JuliaLang/orgs","repos_url":"https://api.github.com/users/JuliaLang/repos","events_url":"https://api.github.com/users/JuliaLang/events{/privacy}","received_events_url":"https://api.github.com/users/JuliaLang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/JuliaLang/julia","description":"The Julia Language: A fresh approach to technical computing.","fork":false,"url":"https://api.github.com/repos/JuliaLang/julia","forks_url":"https://api.github.com/repos/JuliaLang/julia/forks","keys_url":"https://api.github.com/repos/JuliaLang/julia/keys{/key_id}","collaborators_url":"https://api.github.com/repos/JuliaLang/julia/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/JuliaLang/julia/teams","hooks_url":"https://api.github.com/repos/JuliaLang/julia/hooks","issue_events_url":"https://api.github.com/repos/JuliaLang/julia/issues/events{/number}","events_url":"https://api.github.com/repos/JuliaLang/julia/events","assignees_url":"https://api.github.com/repos/JuliaLang/julia/assignees{/user}","branches_url":"https://api.github.com/repos/JuliaLang/julia/branches{/branch}","tags_url":"https://api.github.com/repos/JuliaLang/julia/tags","blobs_url":"https://api.github.com/repos/JuliaLang/julia/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/JuliaLang/julia/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/JuliaLang/julia/git/refs{/sha}","trees_url":"https://api.github.com/repos/JuliaLang/julia/git/trees{/sha}","statuses_url":"https://api.github.com/repos/JuliaLang/julia/statuses/{sha}","languages_url":"https://api.github.com/repos/JuliaLang/julia/languages","stargazers_url":"https://api.github.com/repos/JuliaLang/julia/stargazers","contributors_url":"https://api.github.com/repos/JuliaLang/julia/contributors","subscribers_url":"https://api.github.com/repos/JuliaLang/julia/subscribers","subscription_url":"https://api.github.com/repos/JuliaLang/julia/subscription","commits_url":"https://api.github.com/repos/JuliaLang/julia/commits{/sha}","git_commits_url":"https://api.github.com/repos/JuliaLang/julia/git/commits{/sha}","comments_url":"https://api.github.com/repos/JuliaLang/julia/comments{/number}","issue_comment_url":"https://api.github.com/repos/JuliaLang/julia/issues/comments{/number}","contents_url":"https://api.github.com/repos/JuliaLang/julia/contents/{+path}","compare_url":"https://api.github.com/repos/JuliaLang/julia/compare/{base}...{head}","merges_url":"https://api.github.com/repos/JuliaLang/julia/merges","archive_url":"https://api.github.com/repos/JuliaLang/julia/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/JuliaLang/julia/downloads","issues_url":"https://api.github.com/repos/JuliaLang/julia/issues{/number}","pulls_url":"https://api.github.com/repos/JuliaLang/julia/pulls{/number}","milestones_url":"https://api.github.com/repos/JuliaLang/julia/milestones{/number}","notifications_url":"https://api.github.com/repos/JuliaLang/julia/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/JuliaLang/julia/labels{/name}","releases_url":"https://api.github.com/repos/JuliaLang/julia/releases{/id}","created_at":"2011-04-21T07:01:50Z","updated_at":"2015-03-10T14:59:31Z","pushed_at":"2015-03-10T15:04:24Z","git_url":"git://github.com/JuliaLang/julia.git","ssh_url":"git@github.com:JuliaLang/julia.git","clone_url":"https://github.com/JuliaLang/julia.git","svn_url":"https://github.com/JuliaLang/julia","homepage":"http://julialang.org/","size":179167,"stargazers_count":5197,"watchers_count":5197,"language":"Julia","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1091,"mirror_url":null,"open_issues_count":1183,"forks":1091,"open_issues":1183,"watchers":5197,"default_branch":"master"}},"base":{"label":"JuliaLang:master","ref":"master","sha":"ca79bec2ced0e93aae6445f8a921c6046e473ef5","user":{"login":"JuliaLang","id":743164,"avatar_url":"https://avatars.githubusercontent.com/u/743164?v=3","gravatar_id":"","url":"https://api.github.com/users/JuliaLang","html_url":"https://github.com/JuliaLang","followers_url":"https://api.github.com/users/JuliaLang/followers","following_url":"https://api.github.com/users/JuliaLang/following{/other_user}","gists_url":"https://api.github.com/users/JuliaLang/gists{/gist_id}","starred_url":"https://api.github.com/users/JuliaLang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JuliaLang/subscriptions","organizations_url":"https://api.github.com/users/JuliaLang/orgs","repos_url":"https://api.github.com/users/JuliaLang/repos","events_url":"https://api.github.com/users/JuliaLang/events{/privacy}","received_events_url":"https://api.github.com/users/JuliaLang/received_events","type":"Organization","site_admin":false},"repo":{"id":1644196,"name":"julia","full_name":"JuliaLang/julia","owner":{"login":"JuliaLang","id":743164,"avatar_url":"https://avatars.githubusercontent.com/u/743164?v=3","gravatar_id":"","url":"https://api.github.com/users/JuliaLang","html_url":"https://github.com/JuliaLang","followers_url":"https://api.github.com/users/JuliaLang/followers","following_url":"https://api.github.com/users/JuliaLang/following{/other_user}","gists_url":"https://api.github.com/users/JuliaLang/gists{/gist_id}","starred_url":"https://api.github.com/users/JuliaLang/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JuliaLang/subscriptions","organizations_url":"https://api.github.com/users/JuliaLang/orgs","repos_url":"https://api.github.com/users/JuliaLang/repos","events_url":"https://api.github.com/users/JuliaLang/events{/privacy}","received_events_url":"https://api.github.com/users/JuliaLang/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/JuliaLang/julia","description":"The Julia Language: A fresh approach to technical computing.","fork":false,"url":"https://api.github.com/repos/JuliaLang/julia","forks_url":"https://api.github.com/repos/JuliaLang/julia/forks","keys_url":"https://api.github.com/repos/JuliaLang/julia/keys{/key_id}","collaborators_url":"https://api.github.com/repos/JuliaLang/julia/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/JuliaLang/julia/teams","hooks_url":"https://api.github.com/repos/JuliaLang/julia/hooks","issue_events_url":"https://api.github.com/repos/JuliaLang/julia/issues/events{/number}","events_url":"https://api.github.com/repos/JuliaLang/julia/events","assignees_url":"https://api.github.com/repos/JuliaLang/julia/assignees{/user}","branches_url":"https://api.github.com/repos/JuliaLang/julia/branches{/branch}","tags_url":"https://api.github.com/repos/JuliaLang/julia/tags","blobs_url":"https://api.github.com/repos/JuliaLang/julia/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/JuliaLang/julia/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/JuliaLang/julia/git/refs{/sha}","trees_url":"https://api.github.com/repos/JuliaLang/julia/git/trees{/sha}","statuses_url":"https://api.github.com/repos/JuliaLang/julia/statuses/{sha}","languages_url":"https://api.github.com/repos/JuliaLang/julia/languages","stargazers_url":"https://api.github.com/repos/JuliaLang/julia/stargazers","contributors_url":"https://api.github.com/repos/JuliaLang/julia/contributors","subscribers_url":"https://api.github.com/repos/JuliaLang/julia/subscribers","subscription_url":"https://api.github.com/repos/JuliaLang/julia/subscription","commits_url":"https://api.github.com/repos/JuliaLang/julia/commits{/sha}","git_commits_url":"https://api.github.com/repos/JuliaLang/julia/git/commits{/sha}","comments_url":"https://api.github.com/repos/JuliaLang/julia/comments{/number}","issue_comment_url":"https://api.github.com/repos/JuliaLang/julia/issues/comments{/number}","contents_url":"https://api.github.com/repos/JuliaLang/julia/contents/{+path}","compare_url":"https://api.github.com/repos/JuliaLang/julia/compare/{base}...{head}","merges_url":"https://api.github.com/repos/JuliaLang/julia/merges","archive_url":"https://api.github.com/repos/JuliaLang/julia/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/JuliaLang/julia/downloads","issues_url":"https://api.github.com/repos/JuliaLang/julia/issues{/number}","pulls_url":"https://api.github.com/repos/JuliaLang/julia/pulls{/number}","milestones_url":"https://api.github.com/repos/JuliaLang/julia/milestones{/number}","notifications_url":"https://api.github.com/repos/JuliaLang/julia/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/JuliaLang/julia/labels{/name}","releases_url":"https://api.github.com/repos/JuliaLang/julia/releases{/id}","created_at":"2011-04-21T07:01:50Z","updated_at":"2015-03-10T14:59:31Z","pushed_at":"2015-03-10T15:04:24Z","git_url":"git://github.com/JuliaLang/julia.git","ssh_url":"git@github.com:JuliaLang/julia.git","clone_url":"https://github.com/JuliaLang/julia.git","svn_url":"https://github.com/JuliaLang/julia","homepage":"http://julialang.org/","size":179167,"stargazers_count":5197,"watchers_count":5197,"language":"Julia","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1091,"mirror_url":null,"open_issues_count":1183,"forks":1091,"open_issues":1183,"watchers":5197,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/7906"},"html":{"href":"https://github.com/JuliaLang/julia/pull/7906"},"issue":{"href":"https://api.github.com/repos/JuliaLang/julia/issues/7906"},"comments":{"href":"https://api.github.com/repos/JuliaLang/julia/issues/7906/comments"},"review_comments":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/7906/comments"},"review_comment":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/JuliaLang/julia/pulls/7906/commits"},"statuses":{"href":"https://api.github.com/repos/JuliaLang/julia/statuses/22490c1a6aaa6a12b60bd64554844de5034d153e"}}}}