summaryrefslogtreecommitdiff
path: root/devdocs/c/language%2Foperator_member_access.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/c/language%2Foperator_member_access.html
new repository
Diffstat (limited to 'devdocs/c/language%2Foperator_member_access.html')
-rw-r--r--devdocs/c/language%2Foperator_member_access.html170
1 files changed, 170 insertions, 0 deletions
diff --git a/devdocs/c/language%2Foperator_member_access.html b/devdocs/c/language%2Foperator_member_access.html
new file mode 100644
index 00000000..f455d3f8
--- /dev/null
+++ b/devdocs/c/language%2Foperator_member_access.html
@@ -0,0 +1,170 @@
+ <h1 id="firstHeading" class="firstHeading">Member access operators</h1> <p>Member access operators allow access to the members of their operands.</p>
+<table class="wikitable"> <tr style="text-align:center"> <th> Operator </th> <th> Operator name </th> <th> Example </th> <th> Description </th>
+</tr> <tr style="text-align:center"> <td> <code>[]</code> </td> <td> array subscript </td> <td> <code>a[b]</code> </td> <td> access the <b>b</b>th element of array <b>a</b> </td>
+</tr> <tr style="text-align:center"> <td> <code>*</code> </td> <td> pointer dereference </td> <td> <code>*a</code> </td> <td> dereference the pointer <b>a</b> to access the object or function it refers to </td>
+</tr> <tr style="text-align:center"> <td> <code>&amp;</code> </td> <td> address of </td> <td> <code>&amp;a</code> </td> <td> create a pointer that refers to the object or function <b>a</b> </td>
+</tr> <tr style="text-align:center"> <td> <code>.</code> </td> <td> member access </td> <td> <code>a.b</code> </td> <td> access member <b>b</b> of <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> <b>a</b> </td>
+</tr> <tr style="text-align:center"> <td> <code>-&gt;</code> </td> <td> member access through pointer </td> <td> <code>a-&gt;b</code> </td> <td> access member <b>b</b> of <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> pointed to by <b>a</b> </td>
+</tr>
+</table> <h3 id="Subscript"> Subscript</h3> <p>The array subscript expression has the form</p>
+<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td> <span class="t-spar">pointer-expression</span> <code>[</code> <span class="t-spar">integer-expression</span> <code>]</code> </td> <td> (1) </td> <td class="t-sdsc-nopad"> </td>
+</tr> <tr class="t-sdsc"> <td> <span class="t-spar">integer-expression</span> <code>[</code> <span class="t-spar">pointer-expression</span> <code>]</code> </td> <td> (2) </td> <td class="t-sdsc-nopad"> </td>
+</tr>
+</table> <p>where</p>
+<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">pointer-expression</span> </td> <td> - </td> <td> an <a href="expressions" title="c/language/expressions">expression</a> of type pointer to complete object </td>
+</tr> <tr class="t-par"> <td> <span class="t-spar">integer-expression</span> </td> <td> - </td> <td> an <a href="expressions" title="c/language/expressions">expression</a> of integer type </td>
+</tr>
+</table> <p>The subscript operator expression is an <a href="value_category" title="c/language/value category">lvalue expression</a> whose type is the type of the object pointed to by <span class="t-spar">pointer-expression</span>.</p>
+<p>By definition, the subscript operator <code>E1[E2]</code> is exactly identical to <code>*((E1)+(E2))</code>. If <span class="t-spar">pointer-expression</span> is an array expression, it undergoes <a href="conversion" title="c/language/conversion">lvalue-to-rvalue conversion</a> and becomes a pointer to the first element of the array.</p>
+<p>Due to the definition of the <a href="operator_arithmetic" title="c/language/operator arithmetic">addition between a pointer and an integer</a>, the result is the element of the array with the index equal to the result of <span class="t-spar">integer-expression</span> (or, if <span class="t-spar">pointer-expression</span> was pointing at ith element of some array, the index of the result is i plus the result of <span class="t-spar">integer-expression</span>)</p>
+<p>Note: see <a href="array" title="c/language/array">array</a> for the details on multidimensional arrays.</p>
+<div class="t-example"> <div class="c source-c"><pre data-language="c">#include &lt;stdio.h&gt;
+int main(void)
+{
+ int a[3] = {1,2,3};
+ printf("%d %d\n", a[2], // n == 3
+ 2[a]); // same, n == 3
+ a[2] = 7; // subscripts are lvalues
+
+ int n[2][3] = {{1,2,3},{4,5,6}};
+ int (*p)[3] = &amp;n[1]; // elements of n are arrays
+ printf("%d %d %d\n", (*p)[0], p[0][1], p[0][2]); // access n[1][] via p
+ int x = n[1][2]; // applying [] again to the array n[1]
+ printf("%d\n", x);
+
+ printf("%c %c\n", "abc"[2], 2["abc"]); // string literals are arrays too
+}</pre></div> <p>Output:</p>
+<div class="text source-text"><pre data-language="c">3 3
+4 5 6
+6
+c c</pre></div> </div> <h3 id="Dereference"> Dereference</h3> <p>The <i>dereference</i> or <i>indirection</i> expression has the form</p>
+<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <code>*</code> <span class="t-spar">pointer-expression</span> </td> <td class="t-sdsc-nopad"> </td> <td class="t-sdsc-nopad"> </td>
+</tr>
+</table> <p>where</p>
+<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">pointer-expression</span> </td> <td> - </td> <td> an <a href="expressions" title="c/language/expressions">expression</a> of any pointer type </td>
+</tr>
+</table> <p>If <span class="t-spar">pointer-expression</span> is a pointer to function, the result of the dereference operator is a function designator for that function.</p>
+<p>If <span class="t-spar">pointer-expression</span> is a pointer to object, the result is an <a href="value_category" title="c/language/value category">lvalue expression</a> that designates the pointed-to object.</p>
+<p>Dereferencing a null pointer, a pointer to an object outside of its lifetime (a dangling pointer), a misaligned pointer, or a pointer with indeterminate value is undefined behavior, except when the dereference operator is nullified by applying the address-of operator to its result, as in <code>&amp;*E</code>.</p>
+<div class="t-example"> <div class="c source-c"><pre data-language="c">#include &lt;stdio.h&gt;
+int main(void)
+{
+ int n = 1;
+ int* p = &amp;n;
+ printf("*p = %d\n", *p); // the value of *p is what's stored in n
+ *p = 7; // *p is lvalue
+ printf("*p = %d\n", *p);
+}</pre></div> <p>Output:</p>
+<div class="text source-text"><pre data-language="c">*p = 1
+*p = 7</pre></div> </div> <h3 id="Address_of"> Address of</h3> <p>The address-of expression has the form</p>
+<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td> <code>&amp;</code> <span class="t-spar">function</span> </td> <td> (1) </td> <td class="t-sdsc-nopad"> </td>
+</tr> <tr class="t-sdsc"> <td> <code>&amp;</code> <span class="t-spar">lvalue-expression</span> </td> <td> (2) </td> <td class="t-sdsc-nopad"> </td>
+</tr> <tr class="t-sdsc"> <td> <code>&amp;</code> <code>*</code> <span class="t-spar">expression</span> </td> <td> (3) </td> <td class="t-sdsc-nopad"> </td>
+</tr> <tr class="t-sdsc"> <td> <code>&amp;</code> <span class="t-spar">expression</span> <code>[</code> <span class="t-spar">expression</span> <code>]</code> </td> <td> (4) </td> <td class="t-sdsc-nopad"> </td>
+</tr>
+</table> <div class="t-li1">
+<span class="t-li">1)</span> address of a function</div> <div class="t-li1">
+<span class="t-li">2)</span> address of an object</div> <div class="t-li1">
+<span class="t-li">3)</span> special case: <code>&amp;</code> and <code>*</code> cancel each other, neither one is evaluated</div> <div class="t-li1">
+<span class="t-li">4)</span> special case: <code>&amp;</code> and the <code>*</code> that is implied in <code>[]</code> cancel each other, only the addition implied in <code>[]</code> is evaluated.</div> <p>where</p>
+<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">lvalue-expression</span> </td> <td> - </td> <td> an <a href="value_category" title="c/language/value category">lvalue</a> expression of any type that is not a <a href="bit_field" title="c/language/bit field">bit-field</a> and does not have <a href="storage_duration" title="c/language/storage duration">register</a> storage class </td>
+</tr>
+</table> <p>The address-of operator produces the <a href="value_category" title="c/language/value category">non-lvalue</a> address of its operand, suitable for initializing a pointer to the type of the operand. If the operand is a function designator <span class="t-v">(1)</span>, the result is a pointer to function. If the operand is an object <span class="t-v">(2)</span>, the result is a pointer to object.</p>
+<p>If the operand is the dereference operator, no action is taken (so it's okay to apply &amp;* to a null pointer), except that the result is not an lvalue.</p>
+<p>If the operand is an array index expression, no action is taken other than the array-to-pointer conversion and the addition, so &amp;a[N] is valid for an array of size N (obtaining a pointer one past the end is okay, dereferencing it is not, but dereference cancels out in this expression).</p>
+<div class="t-example"> <div class="c source-c"><pre data-language="c">int f(char c) { return c;}
+int main(void)
+{
+ int n = 1;
+ int *p = &amp;n; // address of object n
+ int (*fp)(char) = &amp;f; // address of function f
+ int a[3] = {1,2,3};
+ int *beg=a, *end=&amp;a[3]; // same as end = a+3
+}</pre></div> </div> <h3 id="Member_access"> Member access</h3> <p>The member access expression has the form</p>
+<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <span class="t-spar">expression</span> <code>.</code> <span class="t-spar">member-name</span> </td> <td class="t-sdsc-nopad"> </td> <td class="t-sdsc-nopad"> </td>
+</tr>
+</table> <p>where</p>
+<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">expression</span> </td> <td> - </td> <td> an expression of <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> type </td>
+</tr> <tr class="t-par"> <td> <span class="t-spar">member-name</span> </td> <td> - </td> <td> an <a href="identifier" title="c/language/identifier">identifier</a> that names a member of the struct or union designated by <span class="t-spar">expression</span> </td>
+</tr>
+</table> <p>The member access expression designates the named member of the <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> designated by its left operand. It has the same <a href="value_category" title="c/language/value category">value category</a> as its left operand.</p>
+<p>If the left operand is <a href="const" title="c/language/const">const</a> or <a href="volatile" title="c/language/volatile">volatile</a> qualified, the result is also qualified. If the left operand is <a href="atomic" title="c/language/atomic">atomic</a>, the behavior is undefined.</p>
+<p>Note: besides identifiers that name objects of struct or union type, the following expressions may have struct or union types: <a href="operator_assignment" title="c/language/operator assignment">assignment</a>, <a href="operator_other#Function_call" title="c/language/operator other">function call</a>, <a href="operator_other#Comma_operator" title="c/language/operator other">comma operator</a>, <a href="operator_other#Conditional_operator" title="c/language/operator other">conditional operator</a>, and <a href="compound_literal" title="c/language/compound literal">compound literal</a>.</p>
+<div class="t-example"> <div class="c source-c"><pre data-language="c">#include &lt;stdio.h&gt;
+struct s {int x;};
+struct s f(void) { return (struct s){1}; }
+int main(void)
+{
+ struct s s;
+ s.x = 1; // ok, changes the member of s
+ int n = f().x; // f() is an expression of type struct s
+// f().x = 1; // Error: this member access expression is not an lvalue
+
+ const struct s sc;
+// sc.x = 3; // Error: sc.x is const, can't be assigned
+
+ union { int x; double d; } u = {1};
+ u.d = 0.1; // changes the active member of the union
+}</pre></div> </div> <h3 id="Member_access_through_pointer"> Member access through pointer</h3> <p>The member access expression has the form</p>
+<table class="t-sdsc-begin"> <tr class="t-sdsc"> <td class="t-sdsc-nopad"> <span class="t-spar">expression</span> <code>-&gt;</code> <span class="t-spar">member-name</span> </td> <td class="t-sdsc-nopad"> </td> <td class="t-sdsc-nopad"> </td>
+</tr>
+</table> <p>where</p>
+<table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">expression</span> </td> <td> - </td> <td> an expression of type <a href="pointer" title="c/language/pointer">pointer</a> to <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> </td>
+</tr> <tr class="t-par"> <td> <span class="t-spar">member-name</span> </td> <td> - </td> <td> an <a href="identifier" title="c/language/identifier">identifier</a> that names a member of the struct or union pointed by <span class="t-spar">expression</span> </td>
+</tr>
+</table> <p>The member access through pointer expression designates the named member of the <a href="struct" title="c/language/struct">struct</a> or <a href="union" title="c/language/union">union</a> type pointed to by its left operand. Its value category is always <a href="value_category" title="c/language/value category">lvalue</a></p>
+<p>If the type pointed to by the left operand is <a href="const" title="c/language/const">const</a> or <a href="volatile" title="c/language/volatile">volatile</a> qualified, the result is also qualified. If the type pointed to by the left operand is <a href="atomic" title="c/language/atomic">atomic</a>, the behavior is undefined.</p>
+<div class="t-example"> <div class="c source-c"><pre data-language="c">#include &lt;stdio.h&gt;
+struct s {int x;};
+int main(void)
+{
+ struct s s={1}, *p = &amp;s;
+ p-&gt;x = 7; // changes the value of s.x through the pointer
+ printf("%d\n", p-&gt;x); // prints 7
+}</pre></div> </div> <h3 id="Defect_reports"> Defect reports</h3> <p>The following behavior-changing defect reports were applied retroactively to previously published C standards.</p>
+<table class="dsctable"> <tr> <th>DR </th> <th>Applied to </th> <th>Behavior as published </th> <th>Correct behavior </th>
+</tr> <tr> <td>
+<a rel="nofollow" class="external text" href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_076.html">DR 076</a> </td> <td>C89 </td> <td>unnessary indirection could not be cancelled by <code>&amp;</code> </td> <td>made cancellable </td>
+</tr>
+</table> <h3 id="References"> References</h3> <ul>
+<li> C17 standard (ISO/IEC 9899:2018): </li>
+<ul>
+<li> 6.5.2.1 Array subscripting (p: 57-58) </li>
+<li> 6.5.2.3 Structure and union members (p: 58-59) </li>
+<li> 6.5.3.2 Address and indirection operators (p: 59-61) </li>
+</ul>
+<li> C11 standard (ISO/IEC 9899:2011): </li>
+<ul>
+<li> 6.5.2.1 Array subscripting (p: 80) </li>
+<li> 6.5.2.3 Structure and union members (p: 82-84) </li>
+<li> 6.5.3.2 Address and indirection operators (p: 88-89) </li>
+</ul>
+<li> C99 standard (ISO/IEC 9899:1999): </li>
+<ul>
+<li> 6.5.2.1 Array subscripting (p: 70) </li>
+<li> 6.5.2.3 Structure and union members (p: 72-74) </li>
+<li> 6.5.3.2 Address and indirection operators (p: 78-79) </li>
+</ul>
+<li> C89/C90 standard (ISO/IEC 9899:1990): </li>
+<ul>
+<li> 3.3.2.1 Array subscripting </li>
+<li> 3.3.2.3 Structure and union members </li>
+<li> 3.3.3.2 Address and indirection operators </li>
+</ul>
+</ul> <h3 id="See_also"> See also</h3> <ul><li> <a href="operator_precedence" title="c/language/operator precedence">Operator precedence</a> </li></ul> <table class="wikitable"> <tr style="text-align:center"> <th colspan="7"> Common operators </th>
+</tr> <tr style="text-align:center"> <td> <a href="operator_assignment" title="c/language/operator assignment"> assignment</a> </td> <td> <a href="operator_incdec" title="c/language/operator incdec"> increment<br>decrement</a> </td> <td> <a href="operator_arithmetic" title="c/language/operator arithmetic"> arithmetic</a> </td> <td> <a href="operator_logical" title="c/language/operator logical"> logical</a> </td> <td> <a href="operator_comparison" title="c/language/operator comparison"> comparison</a> </td> <td> <strong class="selflink"> member<br>access</strong> </td> <td> <a href="operator_other" title="c/language/operator other"> other</a> </td>
+</tr> <tr style="text-align:center"> <td> <p><code>a = b a += b a -= b a *= b a /= b a %= b a &amp;= b a |= b a ^= b a &lt;&lt;= b a &gt;&gt;= b</code></p>
+</td> <td> <p><code>++a --a a++ a--</code></p>
+</td> <td> <p><code>+a -a a + b a - b a * b a / b a % b ~a a &amp; b a | b a ^ b a &lt;&lt; b a &gt;&gt; b</code></p>
+</td> <td> <p><code>!a a &amp;&amp; b a || b</code></p>
+</td> <td> <p><code>a == b a != b a &lt; b a &gt; b a &lt;= b a &gt;= b</code></p>
+</td> <td> <p><code>a[b] *a &amp;a a-&gt;b a.b</code></p>
+</td> <td> <p><code>a(...) a, b (type) a a ? b : c sizeof</code><br><br> <code>_Alignof</code><br><span class="t-mark-rev t-since-c11">(since C11)</span></p>
+</td>
+</tr> </table> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/language/operator_member_access" title="cpp/language/operator member access">C++ documentation</a></span> for <span class=""><span>Member access operators</span></span> </td>
+</tr> </table> <div class="_attribution">
+ <p class="_attribution-p">
+ &copy; cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br>
+ <a href="https://en.cppreference.com/w/c/language/operator_member_access" class="_attribution-link">https://en.cppreference.com/w/c/language/operator_member_access</a>
+ </p>
+</div>