250 lines
32 KiB
HTML
250 lines
32 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>restrict 类型限定符</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-c_language_restrict skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">restrict 类型限定符</h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="c.html">c</a>‎ | <a href="c-language.html">language</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<p>C <a href="c-language-type.html" class="mw-redirect">类型系统</a>中每一个独立的类型在都有数个该类型的<i>限定</i>版本,对应 <a href="c-language-const.html">const</a> 、 <a href="c-language-volatile.html">volatile</a> 及对于指向对象指针的 <i>restrict</i> 限定符中的一个、两个或全部三个。此页面描述 <i>restrict</i> 限定符的效果。</p>
|
|
<p>仅有指向<a href="c-language-type.html" class="mw-redirect">对象类型</a>的指针<span class="t-rev-inl t-since-c23"><span>及其(可能多维的)数组</span> <span><span class="t-mark-rev t-since-c23">(C23 起)</span></span></span>能有 restrict 限定;具体而言,以下是<i>错误</i>的:</p>
|
|
<ul>
|
|
<li><span class="t-c"><span class="mw-geshi c source-c"><span class="kw4">int</span> <span class="kw4">restrict</span> <span class="sy2">*</span>p</span></span></li>
|
|
<li><span class="t-c"><span class="mw-geshi c source-c"><span class="kw4">float</span> <span class="br0">(</span><span class="sy2">*</span> <span class="kw4">restrict</span> f9<span class="br0">)</span><span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span></span></span></li>
|
|
</ul>
|
|
<p>restrict 语义仅应用于左值表达式;例如到 restrict 限定指针的类型转换,或返回 restrict 限定指针的函数调用不是左值,从而该限定符无效果。</p>
|
|
<p>在每个声明声明了 restrict 指针 <code>P</code> 的块(典型例子是函数体的执行,其中 <code>P</code> 为参数)中,若某个对象可由 <code>P</code> 访问(直接或间接)的对象会被任何手段修改,则该块中所有对该对象(读或写)的访问,都必须经由 <code>P</code> 出现,否则行为未定义:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">int</span> n, <span class="kw4">int</span> <span class="sy2">*</span> <span class="kw4">restrict</span> p, <span class="kw4">int</span> <span class="sy2">*</span> <span class="kw4">restrict</span> q<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw1">while</span><span class="br0">(</span>n<span class="sy2">--</span> <span class="sy1">></span> <span class="nu0">0</span><span class="br0">)</span>
|
|
<span class="sy2">*</span>p<span class="sy2">++</span> <span class="sy1">=</span> <span class="sy2">*</span>q<span class="sy2">++</span><span class="sy4">;</span> <span class="co1">// 通过 *p 修改的对象与通过 *q 读取的无一相同</span>
|
|
<span class="co1">// 编译器可以自由地优化、向量化、做页面映射等等。</span>
|
|
<span class="br0">}</span>
|
|
<span class="kw4">void</span> g<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw2">extern</span> <span class="kw4">int</span> d<span class="br0">[</span><span class="nu0">100</span><span class="br0">]</span><span class="sy4">;</span>
|
|
f<span class="br0">(</span><span class="nu0">50</span>, d <span class="sy2">+</span> <span class="nu0">50</span>, d<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK</span>
|
|
f<span class="br0">(</span><span class="nu0">50</span>, d <span class="sy2">+</span> <span class="nu0">1</span>, d<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 未定义行为: d[1] 被 f 中的 p 和 q 一同访问</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>若对象决不被修改,则它可以被别名引用,并被异于 restrict 限定的指针访问(注意若对象为别名引用的 restrict 限定指针所指,则别名引用可能抑制优化)。</p>
|
|
<p>将一个 restrict 指针赋值给另一个是未定义行为,除非将指向外部块的指针赋值给内部块中的指针(包括在调用含 restrict 指针参数的函数时,以 restrict 指针为参数),或从函数返回指针(还有在前一个指针的块已经结束时):</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">int</span><span class="sy2">*</span> <span class="kw4">restrict</span> p1 <span class="sy1">=</span> <span class="sy3">&</span>a<span class="sy4">;</span>
|
|
<span class="kw4">int</span><span class="sy2">*</span> <span class="kw4">restrict</span> p2 <span class="sy1">=</span> <span class="sy3">&</span>b<span class="sy4">;</span>
|
|
p1 <span class="sy1">=</span> p2<span class="sy4">;</span> <span class="co1">// 未定义行为</span></pre></div>
|
|
</div>
|
|
<p>restrict 指针可以自由地赋值给非 restrict 指针,只要编译器还能优化代码,优化机会还是保留就位的:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">int</span> n, <span class="kw4">float</span> <span class="sy2">*</span> <span class="kw4">restrict</span> r, <span class="kw4">float</span> <span class="sy2">*</span> <span class="kw4">restrict</span> s<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw4">float</span> <span class="sy2">*</span> p <span class="sy1">=</span> r, <span class="sy2">*</span> q <span class="sy1">=</span> s<span class="sy4">;</span> <span class="co1">// OK</span>
|
|
<span class="kw1">while</span><span class="br0">(</span>n<span class="sy2">--</span> <span class="sy1">></span> <span class="nu0">0</span><span class="br0">)</span> <span class="sy2">*</span>p<span class="sy2">++</span> <span class="sy1">=</span> <span class="sy2">*</span>q<span class="sy2">++</span><span class="sy4">;</span> <span class="co1">// 几乎肯定优化成仅如 *r++ = *s++ 一般</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-until-c23">
|
|
<td>
|
|
<p>若以 restrict 类型限定符声明数组类型(通过使用 <a href="c-language-typedef.html">typedef</a> ),则数组类型无 restrict 限定,但其元素类型有 restrict 限定:</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-until-c23">(C23 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-c23">
|
|
<td>
|
|
<p>始终认为数组类型与其元素类型同等地拥有 restrict 限定:</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-c23">(C23 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw1">typedef</span> <span class="kw4">int</span> <span class="sy2">*</span>array_t<span class="br0">[</span><span class="nu0">10</span><span class="br0">]</span><span class="sy4">;</span>
|
|
<span class="kw4">restrict</span> array_t a<span class="sy4">;</span> <span class="co1">// a 的类型是 int *restrict[10] </span>
|
|
<span class="co1">// 注: clang 和 icc 以 array_t 不是指针类型为由拒绝</span>
|
|
<span class="kw4">void</span> <span class="sy2">*</span>unqual_ptr <span class="sy1">=</span> <span class="sy3">&</span>a<span class="sy4">;</span> <span class="co1">// C23 前 OK ; C23 起错误</span>
|
|
<span class="co1">// 注: clang 即使在 C89-C17 模式也应用 C++/C23 中的规则</span></pre></div>
|
|
</div>
|
|
<p>在函数声明中,关键词 <code>restrict</code> 可以出现于方括号内,用以声明函数参数的数组类型。它对数组所转换得的指针类型赋予限定:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">int</span> m, <span class="kw4">int</span> n, <span class="kw4">float</span> a<span class="br0">[</span><span class="kw4">restrict</span> m<span class="br0">]</span><span class="br0">[</span>n<span class="br0">]</span>, <span class="kw4">float</span> b<span class="br0">[</span><span class="kw4">restrict</span> m<span class="br0">]</span><span class="br0">[</span>n<span class="br0">]</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="kw4">void</span> g12<span class="br0">(</span><span class="kw4">int</span> n, <span class="kw4">float</span> <span class="br0">(</span><span class="sy2">*</span>p<span class="br0">)</span><span class="br0">[</span>n<span class="br0">]</span><span class="br0">)</span> <span class="br0">{</span>
|
|
f<span class="br0">(</span><span class="nu0">10</span>, n, p, p<span class="sy2">+</span><span class="nu0">10</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK</span>
|
|
f<span class="br0">(</span><span class="nu0">20</span>, n, p, p<span class="sy2">+</span><span class="nu0">10</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 可能是未定义行为(取决于 f 所为)</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>restrict 限定符(像寄存器存储类)是有意使用以促进优化的。而从所有组成一致程序的预处理翻译单元中,删除所有此限定符的实例不会影响其含义(即可观的行为)。</p>
|
|
<p>编译器可以忽略任何一个或全部使用 <code>restrict</code> 的别名使用暗示。</p>
|
|
<p>欲避免未定义行为,程序员应该确保 restrict 限定指针所做的别名引用断言不会违规。</p>
|
|
<p>许多编译器提供作为 <code>restrict</code> 对立面的语言扩展:指示即使指针类型不同,也可以别名使用的属性: <a rel="nofollow" class="external text" href="https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-g_t_0040code_007bmay_005falias_007d-type-attribute-3667">may_alias (gcc)</a></p>
|
|
<h3><span class="mw-headline" id=".E4.BD.BF.E7.94.A8.E6.A8.A1.E5.BC.8F">使用模式</span></h3>
|
|
<p>restrict 限定指针有几种常用的使用模式:</p>
|
|
<h4><span class="mw-headline" id=".E6.96.87.E4.BB.B6.E4.BD.9C.E7.94.A8.E5.9F.9F">文件作用域</span></h4>
|
|
<p>文件作用域的 restrict 限定指针必须在程序运行期间指向单个数组的元素。该数组对象不可以通过 restrict 指针和通过其声明名称(若有的话)或另一个 restrict 指针两种方式一同引用。</p>
|
|
<p>文件作用域 restrict 指针对访问动态分配的全局数组有用; restrict 语义令通过此指针的引用,和通过静态数组的声明名称引用该数组效率相当:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">float</span> <span class="sy2">*</span> <span class="kw4">restrict</span> a, <span class="sy2">*</span> <span class="kw4">restrict</span> b<span class="sy4">;</span>
|
|
<span class="kw4">float</span> c<span class="br0">[</span><span class="nu0">100</span><span class="br0">]</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">int</span> init<span class="br0">(</span><span class="kw4">int</span> n<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw4">float</span> <span class="sy2">*</span> t <span class="sy1">=</span> <a href="c-memory-malloc.html"><span class="kw403">malloc</span></a><span class="br0">(</span><span class="nu0">2</span><span class="sy2">*</span>n<span class="sy2">*</span><span class="kw4">sizeof</span><span class="br0">(</span><span class="kw4">float</span><span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span>
|
|
a <span class="sy1">=</span> t<span class="sy4">;</span> <span class="co1">// a 引用前半</span>
|
|
b <span class="sy1">=</span> t <span class="sy2">+</span> n<span class="sy4">;</span> <span class="co1">// b 引用后半</span>
|
|
<span class="br0">}</span>
|
|
<span class="co1">// 编译器可以从 restrict 限定符推断 a 、 b 和 c 都没有潜在的别名引用</span></pre></div>
|
|
</div>
|
|
<h4><span class="mw-headline" id=".E5.87.BD.E6.95.B0.E5.8F.82.E6.95.B0">函数参数</span></h4>
|
|
<p>最广泛的 restrict 限定指针使用,是用作函数参数。</p>
|
|
<p>在下例中,编译器可能推断出被修改对象不会有别名引用,从而能更大胆地优化循环。在 <code>f</code> 的入口处,必须提供 restrict 指针对关联数组的独占访问。特别是,在 <code>f</code> 内 <code>b</code> 或 <code>c</code> 都不可以指入 <code>a</code> 所关联的数组,因为它们都不是以基于 <code>a</code> 的指针值赋值的。对于 <code>b</code> ,因为其声明的 const 限定符这是显然的,但对于 <code>c</code> ,需要检查 <code>f</code> 的函数体:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">float</span> x<span class="br0">[</span><span class="nu0">100</span><span class="br0">]</span><span class="sy4">;</span>
|
|
<span class="kw4">float</span> <span class="sy2">*</span>c<span class="sy4">;</span>
|
|
<span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">int</span> n, <span class="kw4">float</span> <span class="sy2">*</span> <span class="kw4">restrict</span> a, <span class="kw4">float</span> <span class="sy2">*</span> <span class="kw4">const</span> b<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw4">int</span> i<span class="sy4">;</span>
|
|
<span class="kw1">for</span> <span class="br0">(</span> i<span class="sy1">=</span><span class="nu0">0</span><span class="sy4">;</span> i<span class="sy1"><</span>n<span class="sy4">;</span> i<span class="sy2">++</span> <span class="br0">)</span>
|
|
a<span class="br0">[</span>i<span class="br0">]</span> <span class="sy1">=</span> b<span class="br0">[</span>i<span class="br0">]</span> <span class="sy2">+</span> c<span class="br0">[</span>i<span class="br0">]</span><span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
<span class="kw4">void</span> g3<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw4">float</span> d<span class="br0">[</span><span class="nu0">100</span><span class="br0">]</span>, e<span class="br0">[</span><span class="nu0">100</span><span class="br0">]</span><span class="sy4">;</span>
|
|
c <span class="sy1">=</span> x<span class="sy4">;</span> f<span class="br0">(</span><span class="nu0">100</span>, d, e<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK</span>
|
|
f<span class="br0">(</span> <span class="nu0">50</span>, d, d<span class="sy2">+</span><span class="nu0">50</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK</span>
|
|
f<span class="br0">(</span> <span class="nu0">99</span>, d<span class="sy2">+</span><span class="nu0">1</span>, d<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 未定义行为</span>
|
|
c <span class="sy1">=</span> d<span class="sy4">;</span> f<span class="br0">(</span> <span class="nu0">99</span>, d<span class="sy2">+</span><span class="nu0">1</span>, e<span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 未定义行为</span>
|
|
f<span class="br0">(</span> <span class="nu0">99</span>, e, d<span class="sy2">+</span><span class="nu0">1</span><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// OK</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>注意将 <code>c</code> 指向 <code>b</code> 所关联的数组是允许的。还要注意,对于这些目的,关联到通常指针的“数组”,仅表示数组对象的那一部分实际上是由该指针引用的。</p>
|
|
<p>注意在上例中,编译器能推断 a 和 b 不会别名使用,因为 b 的常性确保这点不会变得依赖函数体。程序员能等价地写 <span class="t-c"><span class="mw-geshi c source-c"><span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">int</span> n, <span class="kw4">float</span> <span class="sy2">*</span> a, <span class="kw4">float</span> <span class="kw4">const</span> <span class="sy2">*</span> <span class="kw4">restrict</span> b<span class="br0">)</span></span></span> ,该情况下编译器理解无法修改通过 b 引用的对象,而以 b 和 a 一同引用的对象也不会被修改。假如程序员要写 <span class="t-c"><span class="mw-geshi c source-c"><span class="kw4">void</span> f<span class="br0">(</span><span class="kw4">int</span> n, <span class="kw4">float</span> <span class="sy2">*</span> <span class="kw4">restrict</span> a, <span class="kw4">float</span> <span class="sy2">*</span> b<span class="br0">)</span></span></span> ,则编译器不检验函数体就无法推断出 a 和 b 不会别名使用。</p>
|
|
<p>通常情况下,最好在函数原型中用 <span class="t-c"><span class="mw-geshi c source-c"><span class="kw4">restrict</span></span></span> 显式标注所有不会别名使用的指针。</p>
|
|
<h4><span class="mw-headline" id=".E5.9D.97.E4.BD.9C.E7.94.A8.E5.9F.9F">块作用域</span></h4>
|
|
<p>一个块作用域的 restrict 限定指针会做一个限于其块内的别名引用断言。它允许局部断言仅应用到重要的块,譬如紧凑循环。它亦使得将使用 restrict 限定指针的函数转换成宏成为可能:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">float</span> x<span class="br0">[</span><span class="nu0">100</span><span class="br0">]</span><span class="sy4">;</span>
|
|
<span class="kw4">float</span> <span class="sy2">*</span>c<span class="sy4">;</span>
|
|
<span class="co2">#define f3(N, A, B) \
|
|
{ int n = (N); \
|
|
float * restrict a = (A); \
|
|
float * const b = (B); \
|
|
int i; \
|
|
for ( i=0; i<n; i++ ) \
|
|
a[i] = b[i] + c[i]; \
|
|
}</span></pre></div>
|
|
</div>
|
|
<h4><span class="mw-headline" id=".E7.BB.93.E6.9E.84.E4.BD.93.E6.88.90.E5.91.98">结构体成员</span></h4>
|
|
<p>作为结构体成员的 restrict 限定指针,所做的别名引用断言作用域,是用于访问该结构体的标识符的作用域。</p>
|
|
<p>即使结构体声明于文件作用域,当用以访问此结构体的标识符拥有块作用域时,结构体中的别名引用断言亦拥有块作用域;别名引用断言仅在块执行或函数调用中生效,具体取决于此结构体类型的对象是如何创造的:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw1">struct</span> t <span class="br0">{</span> <span class="co1">// restrict 指针断言 </span>
|
|
<span class="kw4">int</span> n<span class="sy4">;</span> <span class="co1">// 成员指向无交集的存储区。</span>
|
|
<span class="kw4">float</span> <span class="sy2">*</span> <span class="kw4">restrict</span> p<span class="sy4">;</span>
|
|
<span class="kw4">float</span> <span class="sy2">*</span> <span class="kw4">restrict</span> q<span class="sy4">;</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">void</span> ff<span class="br0">(</span><span class="kw1">struct</span> t r, <span class="kw1">struct</span> t s<span class="br0">)</span> <span class="br0">{</span>
|
|
<span class="kw1">struct</span> t u<span class="sy4">;</span>
|
|
<span class="co1">// r 、 s 、 u 拥有块作用域</span>
|
|
<span class="co1">// r.p 、 r.q 、 s.p 、 s.q 、 u.p 、 u.q 应该在</span>
|
|
<span class="co1">// 每次执行 ff 时全部指向无交集的存储区。</span>
|
|
<span class="co1">// ...</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.85.B3.E9.94.AE.E8.AF.8D">关键词</span></h3>
|
|
<p><a href="c-keyword-restrict.html"><tt>restrict</tt></a></p>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<p>代码生成样例;以 -S ( gcc 、 clang 等)或 /FA ( Visual Studio )参数编译</p>
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="kw4">int</span> foo<span class="br0">(</span><span class="kw4">int</span> <span class="sy2">*</span>a, <span class="kw4">int</span> <span class="sy2">*</span>b<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="sy2">*</span>a <span class="sy1">=</span> <span class="nu0">5</span><span class="sy4">;</span>
|
|
<span class="sy2">*</span>b <span class="sy1">=</span> <span class="nu0">6</span><span class="sy4">;</span>
|
|
<span class="kw1">return</span> <span class="sy2">*</span>a <span class="sy2">+</span> <span class="sy2">*</span>b<span class="sy4">;</span>
|
|
<span class="br0">}</span>
|
|
|
|
<span class="kw4">int</span> rfoo<span class="br0">(</span><span class="kw4">int</span> <span class="sy2">*</span><span class="kw4">restrict</span> a, <span class="kw4">int</span> <span class="sy2">*</span><span class="kw4">restrict</span> b<span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="sy2">*</span>a <span class="sy1">=</span> <span class="nu0">5</span><span class="sy4">;</span>
|
|
<span class="sy2">*</span>b <span class="sy1">=</span> <span class="nu0">6</span><span class="sy4">;</span>
|
|
<span class="kw1">return</span> <span class="sy2">*</span>a <span class="sy2">+</span> <span class="sy2">*</span>b<span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>可能的输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1"># 生成64位Intel平台的代码:
|
|
foo:
|
|
movl $5, (%rdi) # 存储 5 于 *a
|
|
movl $6, (%rsi) # 存储 6 于 *b
|
|
movl (%rdi), %eax # 从 *a 读回值,考虑到前面的存储会修改它
|
|
addl $6, %eax # 将从 *a 读得的值加 6
|
|
ret
|
|
|
|
rfoo:
|
|
movl $11, %eax # 结果是 11,编译时常量
|
|
movl $5, (%rdi) # 存储 5 于 *a
|
|
movl $6, (%rsi) # 存储 6 于 *b
|
|
ret</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.BC.95.E7.94.A8">引用</span></h3>
|
|
<div class="t-ref-std-17">
|
|
<ul>
|
|
<li>C17 标准(ISO/IEC 9899:2018):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.7.3.1 Formal definition of restrict (p: 89-90)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-11">
|
|
<ul>
|
|
<li>C11 标准(ISO/IEC 9899:2011):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.7.3.1 Formal definition of restrict (p: 123-125)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c99">
|
|
<ul>
|
|
<li>C99 标准(ISO/IEC 9899:1999):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>6.7.3.1 Formal definition of restrict (p: 110-112)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|