Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Pointer (computer programming)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Support in various programming languages== ===Ada=== [[Ada (programming language)|Ada]] is a strongly typed language where all pointers are typed and only safe type conversions are permitted. All pointers are by default initialized to <code>null</code>, and any attempt to access data through a <code>null</code> pointer causes an [[Exception handling|exception]] to be raised. Pointers in Ada are called ''[[access type]]s''. Ada 83 did not permit arithmetic on access types (although many compiler vendors provided for it as a non-standard feature), but Ada 95 supports “safe” arithmetic on access types via the package <code>System.Storage_Elements</code>. ===BASIC=== Several old versions of [[BASIC]] for the Windows platform had support for STRPTR() to return the address of a string, and for VARPTR() to return the address of a variable. Visual Basic 5 also had support for OBJPTR() to return the address of an object interface, and for an ADDRESSOF operator to return the address of a function. The types of all of these are integers, but their values are equivalent to those held by pointer types. Newer dialects of [[BASIC]], such as [[FreeBASIC]] or [[BlitzMax]], have exhaustive pointer implementations, however. In FreeBASIC, arithmetic on <code>ANY</code> pointers (equivalent to C's <code>void*</code>) are treated as though the <code>ANY</code> pointer was a byte width. <code>ANY</code> pointers cannot be dereferenced, as in C. Also, casting between <code>ANY</code> and any other type's pointers will not generate any warnings. <syntaxhighlight lang="BlitzMax"> dim as integer f = 257 dim as any ptr g = @f dim as integer ptr i = g assert(*i = 257) assert( (g + 4) = (@f + 1) ) </syntaxhighlight> ===C and C++=== In [[C (programming language)|C]] and [[C++]] pointers are variables that store addresses and can be ''null''. Each pointer has a type it points to, but one can freely cast between pointer types (but not between a function pointer and an object pointer). A special pointer type called the “void pointer” allows pointing to any (non-function) object, but is limited by the fact that it cannot be dereferenced directly (it shall be cast). The address itself can often be directly manipulated by casting a pointer to and from an integral type of sufficient size, though the results are implementation-defined and may indeed cause undefined behavior; while earlier C standards did not have an integral type that was guaranteed to be large enough, [[C99]] specifies the <code>uintptr_t</code> ''[[typedef]] name'' defined in <code>[[C_data_types#Fixed-width_integer_types|<stdint.h>]]</code>, but an implementation need not provide it. [[C++]] fully supports C pointers and C typecasting. It also supports a new group of typecasting operators to help catch some unintended dangerous casts at compile-time. Since [[C++11]], the [[C++ Standard Library|C++ standard library]] also provides [[smart pointer]]s (<code>unique_ptr</code>, <code>shared_ptr</code> and <code>weak_ptr</code>) which can be used in some situations as a safer alternative to primitive C pointers. C++ also supports another form of reference, quite different from a pointer, called simply a ''[[reference (C++)|reference]]'' or ''reference type''. '''Pointer arithmetic''', that is, the ability to modify a pointer's target address with arithmetic operations (as well as magnitude comparisons), is restricted by the language standard to remain within the bounds of a single array object (or just after it), and will otherwise invoke [[undefined behavior]]. Adding or subtracting from a pointer moves it by a multiple of the size of its [[datatype]]. For example, adding 1 to a pointer to 4-byte integer values will increment the pointer's pointed-to byte-address by 4. This has the effect of incrementing the pointer to point at the next element in a contiguous array of integers—which is often the intended result. Pointer arithmetic cannot be performed on <code>void</code> pointers because the [[void type]] has no size, and thus the pointed address can not be added to, although [[GNU Compiler Collection|gcc]] and other compilers will perform byte arithmetic on <code>void*</code> as a non-standard extension, treating it as if it were <code>char *</code>. Pointer arithmetic provides the programmer with a single way of dealing with different types: adding and subtracting the number of elements required instead of the actual offset in bytes. (Pointer arithmetic with <code>char *</code> pointers uses byte offsets, because <code>sizeof(char)</code> is 1 by definition.) In particular, the C definition explicitly declares that the syntax <code>a[n]</code>, which is the <code>n</code>-th element of the array <code>a</code>, is equivalent to <code>*(a + n)</code>, which is the content of the element pointed by <code>a + n</code>. This implies that <code>n[a]</code> is equivalent to <code>a[n]</code>, and one can write, e.g., <code>a[3]</code> or <code>3[a]</code> equally well to access the fourth element of an array <code>a</code>. While powerful, pointer arithmetic can be a source of [[Software bug|computer bugs]]. It tends to confuse novice [[programmer]]s, forcing them into different contexts: an expression can be an ordinary arithmetic one or a pointer arithmetic one, and sometimes it is easy to mistake one for the other. In response to this, many modern high-level computer languages (for example [[Java (programming language)|Java]]) do not permit direct access to memory using addresses. Also, the safe C dialect [[Cyclone programming language|Cyclone]] addresses many of the issues with pointers. See [[C (programming language)#Pointers|C programming language]] for more discussion. The '''<code>void</code> pointer''', or '''<code>void*</code>''', is supported in ANSI C and C++ as a generic pointer type. A pointer to <code>void</code> can store the address of any object (not function),{{efn|Some compilers allow storing the addresses of functions in void pointers. The C++ standard lists converting a function pointer to <code>void*</code> as a conditionally supported feature and the C standard says such conversions are "common extensions". This is required by the [[POSIX]] function <code>dlsym</code>.<ref>{{Cite web |title=CWG Issue 195 |url=https://cplusplus.github.io/CWG/issues/195.html |access-date=2024-02-15 |website=cplusplus.github.io}}</ref>}} and, in C, is implicitly converted to any other object pointer type on assignment, but it must be explicitly cast if dereferenced. [[The C Programming Language|K&R]] C used <code>char*</code> for the “type-agnostic pointer” purpose (before ANSI C). <syntaxhighlight lang="C"> int x = 4; void* p1 = &x; int* p2 = p1; // void* implicitly converted to int*: valid C, but not C++ int a = *p2; int b = *(int*)p1; // when dereferencing inline, there is no implicit conversion </syntaxhighlight> C++ does not allow the implicit conversion of <code>void*</code> to other pointer types, even in assignments. This was a design decision to avoid careless and even unintended casts, though most compilers only output warnings, not errors, when encountering other casts. <syntaxhighlight lang="Cpp"> int x = 4; void* p1 = &x; int* p2 = p1; // this fails in C++: there is no implicit conversion from void* int* p3 = (int*)p1; // C-style cast int* p4 = reinterpret_cast<int*>(p1); // C++ cast </syntaxhighlight> In C++, there is no <code>void&</code> (reference to void) to complement <code>void*</code> (pointer to void), because references behave like aliases to the variables they point to, and there can never be a variable whose type is <code>void</code>. ==== Pointer-to-member ==== <!-- →* redirects here. The correct redirect ->* cannot be made due to technical restrictions (WP:NCTR) --> In C++ pointers to non-static members of a class can be defined. If a class <code>C</code> has a member <code>T a</code> then <code>&C::a</code> is a pointer to the member <code>a</code> of type <code>T C::*</code>. This member can be an object or a [[Function pointer#Method pointers|function]].<ref>{{cite web|url=https://isocpp.org/wiki/faq/pointers-to-members|title=Pointers to Member Functions|access-date=2022-11-26|publisher=isocpp.org}}</ref> They can be used on the right-hand side of operators <code>.*</code> and <code>->*</code> to access the corresponding member. <syntaxhighlight lang="Cpp"> struct S { int a; int f() const {return a;} }; S s1{}; S* ptrS = &s1; int S::* ptr = &S::a; // pointer to S::a int (S::* fp)()const = &S::f; // pointer to S::f s1.*ptr = 1; std::cout << (s1.*fp)() << "\n"; // prints 1 ptrS->*ptr = 2; std::cout << (ptrS->*fp)() << "\n"; // prints 2 </syntaxhighlight> ====Pointer declaration syntax overview==== These pointer declarations cover most variants of pointer declarations. Of course it is possible to have triple pointers, but the main principles behind a triple pointer already exist in a double pointer. The naming used here is what the expression <code>typeid(type).name()</code> equals for each of these types when using [[g++]] or [[clang]].<ref>{{cite web|url=https://linux.die.net/man/1/c++filt|title=c++filt(1) - Linux man page}}</ref><ref>{{cite web|url=http://refspecs.linux-foundation.org/cxxabi-1.83.html#mangling|title=Itanium C++ ABI}}</ref> <syntaxhighlight lang="C"> char A5_A5_c [5][5]; /* array of arrays of chars */ char *A5_Pc [5]; /* array of pointers to chars */ char **PPc; /* pointer to pointer to char ("double pointer") */ char (*PA5_c) [5]; /* pointer to array(s) of chars */ char *FPcvE(); /* function which returns a pointer to char(s) */ char (*PFcvE)(); /* pointer to a function which returns a char */ char (*FPA5_cvE())[5]; /* function which returns pointer to an array of chars */ char (*A5_PFcvE[5])(); /* an array of pointers to functions which return a char */ </syntaxhighlight> The following declarations involving pointers-to-member are valid only in C++: <syntaxhighlight lang="Cpp"> class C; class D; char C::* M1Cc; /* pointer-to-member to char */ char C::*A5_M1Cc [5]; /* array of pointers-to-member to char */ char* C::* M1CPc; /* pointer-to-member to pointer to char(s) */ char C::** PM1Cc; /* pointer to pointer-to-member to char */ char (*M1CA5_c) [5]; /* pointer-to-member to array(s) of chars */ char C::* FM1CcvE(); /* function which returns a pointer-to-member to char */ char D::* C::* M1CM1Dc; /* pointer-to-member to pointer-to-member to pointer to char(s) */ char C::* C::* M1CMS_c; /* pointer-to-member to pointer-to-member to pointer to char(s) */ char (C::* FM1CA5_cvE())[5]; /* function which returns pointer-to-member to an array of chars */ char (C::* M1CFcvE)() /* pointer-to-member-function which returns a char */ char (C::* A5_M1CFcvE[5])(); /* an array of pointers-to-member-functions which return a char */ </syntaxhighlight> The <code>()</code> and <code>[]</code> have a higher priority than <code>*</code>. <ref>Ulf Bilting, Jan Skansholm, "Vägen till C" (the Road to C), third edition, page 169, {{ISBN|91-44-01468-6}}</ref> ===C#=== In the [[C Sharp (programming language)|C# programming language]], pointers are supported by either marking blocks of code that include pointers with the <code>unsafe</code> keyword, or by <code>using</code> the <code>System.Runtime.CompilerServices</code> assembly provisions for pointer access. The syntax is essentially the same as in C++, and the address pointed can be either [[Managed code|managed]] or [[Managed code|unmanaged]] memory. However, pointers to managed memory (any pointer to a managed object) must be declared using the <code>fixed</code> keyword, which prevents the [[Garbage collection (computer science)|garbage collector]] from moving the pointed object as part of memory management while the pointer is in scope, thus keeping the pointer address valid. However, an exception to this is from using the <code>IntPtr</code> structure, which is a memory managed equivalent to <code>int*</code>, and does not require the <code>unsafe</code> keyword nor the <code>CompilerServices</code> assembly. This type is often returned when using methods from the <code>System.Runtime.InteropServices</code>, for example: <syntaxhighlight lang="csharp"> // Get 16 bytes of memory from the process's unmanaged memory IntPtr pointer = System.Runtime.InteropServices.Marshal.AllocHGlobal(16); // Do something with the allocated memory // Free the allocated memory System.Runtime.InteropServices.Marshal.FreeHGlobal(pointer); </syntaxhighlight> The [[.NET Framework|.NET framework]] includes many classes and methods in the <code>System</code> and <code>System.Runtime.InteropServices</code> namespaces (such as the <code>Marshal</code> class) which convert .NET types (for example, <code>System.String</code>) to and from many [[Managed code|unmanaged]] types and pointers (for example, <code>LPWSTR</code> or <code>void*</code>) to allow communication with [[Managed code|unmanaged code]]. Most such methods have the same security permission requirements as unmanaged code, since they can affect arbitrary places in memory. ===COBOL=== The [[COBOL]] programming language supports pointers to variables. Primitive or group (record) data objects declared within the <code>LINKAGE SECTION</code> of a program are inherently pointer-based, where the only memory allocated within the program is space for the address of the data item (typically a single memory word). In program source code, these data items are used just like any other <code>WORKING-STORAGE</code> variable, but their contents are implicitly accessed indirectly through their <code>LINKAGE</code> pointers. Memory space for each pointed-to data object is typically [[dynamic memory allocation|allocated dynamically]] using external [[subroutine|<code>CALL</code>]] statements or via embedded extended language constructs such as [[EXEC CICS|<code>EXEC CICS</code>]] or [[SQL|<code>EXEC SQL</code>]] statements. Extended versions of COBOL also provide pointer variables declared with <code>USAGE</code> <code>IS</code> <code>POINTER</code> clauses. The values of such pointer variables are established and modified using <code>SET</code> and <code>SET</code> <code>ADDRESS</code> statements. Some extended versions of COBOL also provide <code>PROCEDURE-POINTER</code> variables, which are capable of storing the [[function pointer|addresses of executable code]]. ===PL/I=== The [[PL/I]] language provides full support for pointers to all data types (including pointers to structures), [[recursion]], [[Computer multitasking|multitasking]], string handling, and extensive built-in [[subroutine|function]]s. PL/I was quite a leap forward compared to the programming languages of its time.{{citation needed|date=February 2014}} PL/I pointers are untyped, and therefore no casting is required for pointer dereferencing or assignment. The declaration syntax for a pointer is <code>DECLARE xxx POINTER;</code>, which declares a pointer named "xxx". Pointers are used with <code>BASED</code> variables. A based variable can be declared with a default locator (<code>DECLARE xxx BASED(ppp);</code> or without (<code>DECLARE xxx BASED;</code>), where xxx is a based variable, which may be an element variable, a structure, or an array, and ppp is the default pointer). Such a variable can be address without an explicit pointer reference (<code>xxx=1;</code>, or may be addressed with an explicit reference to the default locator (ppp), or to any other pointer (<code>qqq->xxx=1;</code>). Pointer arithmetic is not part of the PL/I standard, but many compilers allow expressions of the form <code>ptr = ptr±expression</code>. IBM PL/I also has the builtin function <code>PTRADD</code> to perform the arithmetic. Pointer arithmetic is always performed in bytes. IBM ''Enterprise'' PL/I compilers have a new form of typed pointer called a <code>HANDLE</code>. ===D=== The [[D (programming language)|D programming language]] is a derivative of C and C++ which fully supports C pointers and C typecasting. ===Eiffel=== The [[Eiffel (programming language)|Eiffel object-oriented language]] employs value and reference semantics without pointer arithmetic. Nevertheless, pointer classes are provided. They offer pointer arithmetic, typecasting, explicit memory management, interfacing with non-Eiffel software, and other features. ===Fortran=== [[Fortran|Fortran-90]] introduced a strongly typed pointer capability. Fortran pointers contain more than just a simple memory address. They also encapsulate the lower and upper bounds of array dimensions, strides (for example, to support arbitrary array sections), and other metadata. An ''association operator'', <code>=></code> is used to associate a <code>POINTER</code> to a variable which has a <code>TARGET</code> attribute. The Fortran-90 <code>ALLOCATE</code> statement may also be used to associate a pointer to a block of memory. For example, the following code might be used to define and create a linked list structure: <syntaxhighlight lang="Fortran"> type real_list_t real :: sample_data(100) type (real_list_t), pointer :: next => null () end type type (real_list_t), target :: my_real_list type (real_list_t), pointer :: real_list_temp real_list_temp => my_real_list do read (1,iostat=ioerr) real_list_temp%sample_data if (ioerr /= 0) exit allocate (real_list_temp%next) real_list_temp => real_list_temp%next end do </syntaxhighlight> Fortran-2003 adds support for procedure pointers. Also, as part of the ''C Interoperability'' feature, Fortran-2003 supports intrinsic functions for converting C-style pointers into Fortran pointers and back. ===Go=== [[Go (programming language)|Go]] has pointers. Its declaration syntax is equivalent to that of C, but written the other way around, ending with the type. Unlike C, Go has garbage collection, and disallows pointer arithmetic. Reference types, like in C++, do not exist. Some built-in types, like maps and channels, are boxed (i.e. internally they are pointers to mutable structures), and are initialized using the <code>make</code> function. In an approach to unified syntax between pointers and non-pointers, the arrow (<code>-></code>) operator has been dropped: the dot operator on a pointer refers to the field or method of the dereferenced object. This, however, only works with 1 level of indirection. ===Java=== There is no explicit representation of pointers in [[Java (programming language)|Java]]. Instead, more complex data structures like [[Object-oriented programming|objects]] and [[Array data structure|arrays]] are implemented using [[reference (computer science)|references]]. The language does not provide any explicit pointer manipulation operators. It is still possible for code to attempt to dereference a null reference (null pointer), however, which results in a run-time [[exception handling|exception]] being thrown. The space occupied by unreferenced memory objects is recovered automatically by [[garbage collection (computer science)|garbage collection]] at run-time.<ref>Nick Parlante, [http://cslibrary.stanford.edu/102/PointersAndMemory.pdf#%22Pointers%20and%20Memory%22], [http://cslibrary.stanford.edu# Stanford Computer Science Education Library], pp. 9–10 (2000).</ref> ===Modula-2=== Pointers are implemented very much as in Pascal, as are <code>VAR</code> parameters in procedure calls. [[Modula-2]] is even more strongly typed than Pascal, with fewer ways to escape the type system. Some of the variants of Modula-2 (such as [[Modula-3]]) include garbage collection. <!-- +++assistance is needed here+++ --> ===Oberon=== Much as with Modula-2, pointers are available. There are still fewer ways to evade the type system and so [[Oberon (programming language)|Oberon]] and its variants are still safer with respect to pointers than Modula-2 or its variants. As with [[Modula-3]], garbage collection is a part of the language specification. <!-- +++assistance is needed here+++ --> ===Pascal=== Unlike many languages that feature pointers, standard [[International Organization for Standardization|ISO]] [[Pascal (programming language)|Pascal]] only allows pointers to reference dynamically created variables that are anonymous and does not allow them to reference standard static or local variables.<ref>ISO 7185 Pascal Standard (unofficial copy), section [http://standardpascal.org/iso7185.html#6.4.4%20Pointer-types 6.4.4 Pointer-types] {{Webarchive|url=https://web.archive.org/web/20170424183023/http://www.standardpascal.org/iso7185.html#6.4.4%20Pointer-types |date=2017-04-24}} and subsequent.</ref> It does not have pointer arithmetic. Pointers also must have an associated type and a pointer to one type is not compatible with a pointer to another type (e.g. a pointer to a char is not compatible with a pointer to an integer). This helps eliminate the type security issues inherent with other pointer implementations, particularly those used for [[PL/I]] or [[C (Programming Language)|C]]. It also removes some risks caused by [[dangling pointers]], but the ability to dynamically let go of referenced space by using the <code>dispose</code> standard procedure (which has the same effect as the <code>free</code> library function found in [[C (Programming Language)|C]]) means that the risk of dangling pointers has not been entirely eliminated.<ref>J. Welsh, W. J. Sneeringer, and C. A. R. Hoare, "Ambiguities and Insecurities in Pascal," ''Software: Practice and Experience 7'', pp. 685–696 (1977)</ref> However, in some commercial and open source Pascal (or derivatives) compiler implementations —like [[Free Pascal]],<ref>Free Pascal Language Reference guide, section [http://www.freepascal.org/docs-html/ref/refse15.html#x43-490003.4 3.4 Pointers]</ref> [[Turbo Pascal]] or the [[Object Pascal]] in [[Embarcadero Delphi]]— a pointer is allowed to reference standard static or local variables and can be cast from one pointer type to another. Moreover, pointer arithmetic is unrestricted: adding or subtracting from a pointer moves it by that number of bytes in either direction, but using the <code>Inc</code> or <code>Dec</code> standard procedures with it moves the pointer by the size of the [[data type]] it is ''declared'' to point to. An untyped pointer is also provided under the name <code>Pointer</code>, which is compatible with other pointer types. ===Perl=== The [[Perl]] [[programming language]] supports pointers, although rarely used, in the form of the pack and unpack functions. These are intended only for simple interactions with compiled OS libraries. In all other cases, Perl uses [[Reference (computer science)|references]], which are typed and do not allow any form of pointer arithmetic. They are used to construct complex data structures.<ref>{{cite web|author=Contact details |url=http://perldoc.perl.org/perlref.html#Making-References |title=// Making References (Perl References and nested data structures) |publisher=Perldoc.perl.org |access-date=2018-04-13}}</ref>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)