<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Thanks.  I know it works in practice on Linux.  I just can’t figure out if the C standard’s notion of an array object includes Linux’s flat virtual address space or if it means specific C arrays.<div><br></div><div>Subtraction seems like an unnecessary way to cast to ptrdiff_t, but obviously it works.</div><div><br></div><div>My primary goal here is understanding what, if any, impact it will have to remove all the segmented addressing text from the standard.</div><div><br></div><div>Jeff<br><div><br><blockquote type="cite"><div>On 23. Jan 2024, at 4.55, Zhou, Hui <zhouh@anl.gov> wrote:</div><br class="Apple-interchange-newline"><div><meta charset="UTF-8"><div class="elementToProof" style="font-size: 12pt; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif;">At least for Linux, Windows, and osX, we are using non-segmented virtual address, thus all address points to (at least in principle) the same array object. Thus, it is not undefined.</div><div class="elementToProof" style="font-size: 12pt; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif;"><br></div><div class="elementToProof" style="font-size: 12pt; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif;">The<span class="Apple-converted-space"> </span><code>#ifdef CHAR_PTR_IS_ADDRESS</code>​ branch casts pointer to<span class="Apple-converted-space"> </span><code>MPI_Aint</code>​.</div><div class="elementToProof" style="font-size: 12pt; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif;"><br></div><div class="elementToProof" style="font-size: 12pt; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif;">The alternative branch casts<span class="Apple-converted-space"> </span><code>ptrdiff_t</code>​ to<span class="Apple-converted-space"> </span><code>MPI_Aint</code>​.<br></div><div class="elementToProof" style="font-size: 12pt; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif;"><br></div><div class="elementToProof" style="font-size: 12pt; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif;">--<span class="Apple-converted-space"> </span><br></div><div class="elementToProof" style="font-size: 12pt; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; font-family: Aptos, Aptos_EmbeddedFont, Aptos_MSFontService, Calibri, Helvetica, sans-serif;">Hui<br></div><div id="appendonsend" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 16px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;"></div><hr tabindex="-1" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 16px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; display: inline-block; width: 754.59375px;"><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 16px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none; float: none; display: inline !important;"></span><div id="divRplyFwdMsg" dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 16px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;"><font face="Calibri, sans-serif" style="font-size: 11pt;"><b>From:</b><span class="Apple-converted-space"> </span>Jeff Hammond via devel <devel@mpich.org><br><b>Sent:</b><span class="Apple-converted-space"> </span>Monday, January 22, 2024 1:46 AM<br><b>To:</b><span class="Apple-converted-space"> </span>MPICH <devel@mpich.org><br><b>Cc:</b><span class="Apple-converted-space"> </span>Jeff Hammond <jeff.science@gmail.com><br><b>Subject:</b><span class="Apple-converted-space"> </span>[mpich-devel] MPIR_Get_address_impl</font><div> </div></div><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 16px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;"><div dir="ltr">I am trying to understand MPI_Get_address and its interactions with C better.  I've included the relevant text from C89 and C23 on pointer subtraction at the bottom.<div><br></div><div>As best I can tell, MPICH's "portable" way to generate an address is undefined behavior unless pointers behave as if they point to the same array object, which is always true only when MPI_BOTTOM is zero.  Thus, subtraction of MPI_BOTTOM is pointless: it either has no effect or is undefined behavior.</div><div><br></div><div>The SX-4 workaround from the late 1990s is caused by a compiler bug, unless the SX-4 C compiler defines ptrdiff_t to be int, which would be nonsensical on a 64-bit system.  However, the workaround is actually the correct implementation, based on the previous paragraph.</div><div><br></div><div>Does this make sense?</div><div><br></div><div>Jeff<br><br>int MPIR_Get_address_impl(const void *location, MPI_Aint * address)<br>{<br>    /* SX_4 needs to set CHAR_PTR_IS_ADDRESS<br>     * The reason is that it computes the different in two pointers in<br>     * an "int", and addresses typically have the high (bit 31) bit set;<br>     * thus the difference, when cast as MPI_Aint (long), is sign-extended,<br>     * making the absolute address negative.  Without a copy of the C<br>     * standard, I can't tell if this is a compiler bug or a language bug.<br>     */<br>#ifdef CHAR_PTR_IS_ADDRESS<br>    *address = (MPI_Aint) location;<br>#else<br>    /* Note that this is the "portable" way to generate an address.<br>     * The difference of two pointers is the number of elements<br>     * between them, so this gives the number of chars between location<br>     * and ptr.  As long as sizeof(char) represents one byte,<br>     * of bytes from 0 to location */<br>    *address = (MPI_Aint) ((char *) location - (char *) MPI_BOTTOM);<br>#endif<br>    /* The same code is used in MPI_Address */<br>    return MPI_SUCCESS;<br>}<br><br>ANSI/ISO 9899:1990</div><div><br></div><div>6.3.6 Additive operators<br>"When two pointers to elements of the same array object are subtracted, the result is the difference of the subscripts of the two array elements. The size of the result is implementation-defined. and its type (a signed integral type) is ptrdiff_t defined in the <stddef. h> header. As with any other arithmetic overflow, if the result does not fit in the space provided, the behavior is undefined. In other words, if the expressions P and Q point to, respectively, the i-th and j-th elements of an array object, the expression (P)-(Q) has the value i-j provided the value fits in an object of type ptrdiff_t. Moreover, if the expression P points either to an element of an array object or one past the last element of an array object, and the expression Q points IO the last element of the same array object. the expression ((Q)+1) - (P) has the same value as ((Q) - (P))+1 and as -((P)- ((Q)+1)), and has the value zero if the expression P points one past the last element of the array object, even though the expression (Q)+1 does not point to an element of the array object. Unless both pointers point to elements of the same array object, or one past the last element of the array object, the behavior is undefined."</div><br>G.2 Undefined behavior<br>"Pointers that do not behave as if they point to the same array object are subtracted (6.3.6)."<div><br><div>ISO/IEC 9899:2023<div><span style="font-family: Times; font-size: 16px;">§6.5.6 </span>Additive operators<div title="Page 95"><div><div><ol start="4" style="list-style-type: none;"><li><p style="margin-top: 0px; margin-bottom: 0px;"></p><div class="x_gmail-page" title="Page 104"><div class="x_gmail-layoutArea"><div class="x_gmail-column"></div></div></div></li><li><span style="font-size: 8pt; font-family: URWPalladioL;">10  </span><span style="font-size: 10pt; font-family: URWPalladioL;">When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements. The size of the result is implementation-defined, and its type (a signed integer type) is<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono; font-weight: 700; color: rgb(0, 0, 140);">ptrdiff</span><span style="font-size: 9pt; font-family: BeraSansMono; font-weight: 700; color: rgb(0, 0, 140); vertical-align: 2pt;">_</span><span style="font-size: 9pt; font-family: BeraSansMono; font-weight: 700; color: rgb(0, 0, 140);">t<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">defined in the<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono;"><stddef.h><span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">header. If the result is not representable in an object of that type, the behavior is undefined. In other words, if the expressions<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">P<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">and<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">Q<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">point to, respectively, the<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: CMMI10;">i</span><span style="font-size: 10pt; font-family: URWPalladioL;">-th and<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: CMMI10;">j</span><span style="font-size: 10pt; font-family: URWPalladioL;">-th elements of an array object, the expression<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono;">(</span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">P</span><span style="font-size: 9pt; font-family: BeraSansMono;">)-(</span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">Q</span><span style="font-size: 9pt; font-family: BeraSansMono;">)<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">has the value<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: CMMI10;">i<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: CMSY10;">−<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: CMMI10;">j<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">provided the value fits in an object of type<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono; font-weight: 700; color: rgb(0, 0, 140);">ptrdiff</span><span style="font-size: 9pt; font-family: BeraSansMono; font-weight: 700; color: rgb(0, 0, 140); vertical-align: 2pt;">_</span><span style="font-size: 9pt; font-family: BeraSansMono; font-weight: 700; color: rgb(0, 0, 140);">t</span><span style="font-size: 10pt; font-family: URWPalladioL;">. Moreover, if the expression<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">P<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">points either to an element of an array object or one past the last element of an array object, and the expression<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">Q<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">points to the last element of the same array object, the expression<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono;">((</span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">Q</span><span style="font-size: 9pt; font-family: BeraSansMono;">)+1)-(</span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">P</span><span style="font-size: 9pt; font-family: BeraSansMono;">)<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">has the same value as<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono;">((</span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">Q</span><span style="font-size: 9pt; font-family: BeraSansMono;">)-(</span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">P</span><span style="font-size: 9pt; font-family: BeraSansMono;">))+1<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">and as<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono;">-((</span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">P</span><span style="font-size: 9pt; font-family: BeraSansMono;">)-((</span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">Q</span><span style="font-size: 9pt; font-family: BeraSansMono;">)+1))</span><span style="font-size: 10pt; font-family: URWPalladioL;">, and has the value zero if the expression<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">P<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">points one past the last element of the array object, even though the expression<span class="Apple-converted-space"> </span></span><span style="font-size: 9pt; font-family: BeraSansMono;">(</span><span style="font-size: 9pt; font-family: BeraSansMono; color: rgb(0, 0, 140);">Q</span><span style="font-size: 9pt; font-family: BeraSansMono;">)+1<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">does not point to an element of the array object.</span><span style="font-size: 7pt; font-family: URWPalladioL; vertical-align: 4pt;">119) </span><br></li><ol start="2" style="list-style-type: none;"></ol></ol></div></div></div><ol></ol></div></div></div><br><div class="x_gmail-page" title="Page 604"><div class="x_gmail-layoutArea"><div class="x_gmail-column"><div style="margin-top: 0px; margin-bottom: 0px;"><span style="font-size: 12pt; font-family: URWPalladioL; font-weight: 700;">J.2 Undefined behavior</span></div><div style="margin-top: 0px; margin-bottom: 0px;"><span style="font-size: 8pt; font-family: URWPalladioL;">1<span class="Apple-converted-space"> </span></span><span style="font-size: 10pt; font-family: URWPalladioL;">The behavior is undefined in the following circumstances: </span></div></div></div></div><div class="x_gmail-page" title="Page 605"><div class="x_gmail-layoutArea"><div class="x_gmail-column"><div style="margin-top: 0px; margin-bottom: 0px;"><span style="font-size: 10pt; font-family: URWPalladioL;">(43) Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object (6.5.6). </span></div></div></div></div><br>--<br>Jeff Hammond<br><a href="mailto:jeff.science@gmail.com" target="_blank">jeff.science@gmail.com</a><br><a href="http://jeffhammond.github.io/" target="_blank">http://jeffhammond.github.io/</a></div></div></div></blockquote></div><br></div></body></html>