172 lines
16 KiB
HTML
172 lines
16 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>alignas 说明符 (C++11 起)</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-cpp_language_alignas skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">alignas 说明符 <span class="t-mark-rev t-since-cxx11">(C++11 起)</span></h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="cpp.html">cpp</a>‎ | <a href="cpp-language.html">language</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<p>指定类型或对象的<a href="cpp-language-object.html#.E5.AF.B9.E9.BD.90">对齐要求</a>。</p>
|
|
<h3><span class="mw-headline" id=".E8.AF.AD.E6.B3.95">语法</span></h3>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td class="t-sdsc-nopad"><code><b>alignas(</b></code> <span class="t-spar">表达式</span> <code><b>)</b></code></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td class="t-sdsc-nopad"><code><b>alignas(</b></code> <span class="t-spar">类型标识</span> <code><b>)</b></code></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td class="t-sdsc-nopad"><code><b>alignas(</b></code> <span class="t-spar">包</span> <code><b>...</b></code> <code><b>)</b></code></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<div class="t-li1"><span class="t-li">1)</span> <span class="t-c"><span class="mw-geshi cpp source-cpp">alignas<span class="br0">(</span>表达式<span class="br0">)</span></span></span> 必须是求值为零或合法的<a href="cpp-language-object.html#.E5.AF.B9.E9.BD.90">对齐</a>或扩展对齐的<a href="cpp-language-constant_expression.html#.E6.95.B4.E5.9E.8B.E5.B8.B8.E9.87.8F.E8.A1.A8.E8.BE.BE.E5.BC.8F">整型常量表达式</a>。</div>
|
|
<div class="t-li1"><span class="t-li">2)</span> 等价于 <span class="t-c"><span class="mw-geshi cpp source-cpp">alignas<span class="br0">(</span>alignof<span class="br0">(</span>类型<span class="br0">)</span><span class="br0">)</span></span></span></div>
|
|
<div class="t-li1"><span class="t-li">3)</span> 等价于对同一说明应用多个 alignas 说明符,逐个对应于<a href="cpp-language-parameter_pack.html">形参包</a>的各个成员,形参包可以是类型或非类型形参包。</div>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p><span class="t-c"><span class="mw-geshi cpp source-cpp">alignas</span></span> 说明符可应用于:</p>
|
|
<ul>
|
|
<li><a href="cpp-language-class.html">类/结构体/联合体</a>或<a href="cpp-language-enum.html">枚举</a>的声明或定义;</li>
|
|
<li>非位域类数据成员的声明;</li>
|
|
<li>变量声明,除了它不能应用于下列内容:
|
|
<ul>
|
|
<li>函数形参;</li>
|
|
<li>catch 子句的异常形参。</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<p>这种声明所声明的对象或类型的<a href="cpp-language-object.html#.E5.AF.B9.E9.BD.90">对齐要求</a>将等于用于该声明的所有 <code>alignas</code> 说明符中最严格(最大)的非零 <span class="t-spar">表达式</span>,除非这会削弱类型的自然对齐。</p>
|
|
<p>如果某个声明上的最严格(最大)<code>alignas</code> 比当它没有任何 <code>alignas</code> 说明符的情况下本应有的对齐更弱(即弱于其原生对齐,或弱于同一对象或类型的另一声明上的 <code>alignas</code>),那么程序非良构:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="kw1">struct</span> alignas<span class="br0">(</span><span class="nu0">8</span><span class="br0">)</span> S <span class="br0">{</span><span class="br0">}</span><span class="sy4">;</span>
|
|
<span class="kw1">struct</span> alignas<span class="br0">(</span><span class="nu0">1</span><span class="br0">)</span> U <span class="br0">{</span> S s<span class="sy4">;</span> <span class="br0">}</span><span class="sy4">;</span> <span class="co1">// 错误:如果没有 alignas(1) 则 U 的对齐将为 8</span></pre></div>
|
|
</div>
|
|
<p>无效的非零对齐,例如 <span class="t-c"><span class="mw-geshi cpp source-cpp">alignas<span class="br0">(</span><span class="nu0">3</span><span class="br0">)</span></span></span> 非良构。</p>
|
|
<p>同一声明上,弱于其他 <span class="t-c"><span class="mw-geshi cpp source-cpp">alignas</span></span> 的有效的非零对齐被忽略。</p>
|
|
<p>始终忽略 <span class="t-c"><span class="mw-geshi cpp source-cpp">alignas<span class="br0">(</span><span class="nu0">0</span><span class="br0">)</span></span></span>。</p>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>按 ISO C11 标准,C 语言有 <span class="t-c"><span class="mw-geshi cpp source-cpp">_Alignas</span></span> 关键词,并于头文件 <a href="c-types.html"><tt><stdalign.h></tt></a> 中将 <span class="t-c"><span class="mw-geshi cpp source-cpp">alignas</span></span> 定义为展开成该关键词的预处理器宏。</p>
|
|
<p>在 C++ 中这是关键词,且</p>
|
|
<table class="t-rev-begin">
|
|
<tr class="t-rev t-until-cxx20">
|
|
<td>
|
|
<p>头文件 <a href="cpp-header.html#.E6.97.A0.E6.84.8F.E4.B9.89.E7.9A.84_C_.E5.A4.B4.E6.96.87.E4.BB.B6"><tt><stdalign.h></tt></a> 与 <a href="cpp-header-cstdalign.html"><tt><cstdalign></tt></a> 并不定义这个宏。不过它们仍定义宏常量 <span class="t-c"><span class="mw-geshi cpp source-cpp">__alignas_is_defined</span></span>。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-until-cxx20">(C++20 前)</span></td>
|
|
</tr>
|
|
<tr class="t-rev t-since-cxx20">
|
|
<td>
|
|
<p>头文件 <a href="cpp-header.html#.E6.97.A0.E6.84.8F.E4.B9.89.E7.9A.84_C_.E5.A4.B4.E6.96.87.E4.BB.B6"><tt><stdalign.h></tt></a> 并不定义这个宏。不过它仍定义宏常量 <span class="t-c"><span class="mw-geshi cpp source-cpp">__alignas_is_defined</span></span>。</p>
|
|
</td>
|
|
<td><span class="t-mark-rev t-since-cxx20">(C++20 起)</span></td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E5.85.B3.E9.94.AE.E8.AF.8D">关键词</span></h3>
|
|
<p><a href="cpp-keyword-alignas.html"><tt>alignas</tt></a></p>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="cpp source-cpp">
|
|
<pre class="de1"><span class="co1">// 每个 struct_float 类型对象都将被对齐到 alignof(float) 边界</span>
|
|
<span class="co1">// (通常为 4):</span>
|
|
<span class="kw1">struct</span> alignas<span class="br0">(</span>alignof<span class="br0">(</span><span class="kw4">float</span><span class="br0">)</span><span class="br0">)</span> struct_float
|
|
<span class="br0">{</span>
|
|
<span class="co1">// 定义在此</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// sse_t 类型的每个对象将对齐到 32 字节边界</span>
|
|
<span class="kw1">struct</span> alignas<span class="br0">(</span><span class="nu0">32</span><span class="br0">)</span> sse_t
|
|
<span class="br0">{</span>
|
|
<span class="kw4">float</span> sse_data<span class="br0">[</span><span class="nu0">4</span><span class="br0">]</span><span class="sy4">;</span>
|
|
<span class="br0">}</span><span class="sy4">;</span>
|
|
|
|
<span class="co1">// 数组 "cacheline" 将对齐到 64 字节边界</span>
|
|
alignas<span class="br0">(</span><span class="nu0">64</span><span class="br0">)</span> <span class="kw4">char</span> cacheline<span class="br0">[</span><span class="nu0">64</span><span class="br0">]</span><span class="sy4">;</span>
|
|
|
|
|
|
<span class="co2">#include <iostream></span>
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw1">struct</span> default_aligned <span class="br0">{</span> <span class="kw4">float</span> data<span class="br0">[</span><span class="nu0">4</span><span class="br0">]</span><span class="sy4">;</span> <span class="br0">}</span> a, b, c<span class="sy4">;</span>
|
|
sse_t x, y, z<span class="sy4">;</span>
|
|
|
|
<a href="cpp-io-cout.html"><span class="kw1758">std::<span class="me2">cout</span></span></a>
|
|
<span class="sy1"><<</span> <span class="st0">"alignof(struct_float) = "</span> <span class="sy1"><<</span> alignof<span class="br0">(</span>struct_float<span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span>
|
|
<span class="sy1"><<</span> <span class="st0">"sizeof(sse_t) = "</span> <span class="sy1"><<</span> sizeof<span class="br0">(</span>sse_t<span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span>
|
|
<span class="sy1"><<</span> <span class="st0">"alignof(sse_t) = "</span> <span class="sy1"><<</span> alignof<span class="br0">(</span>sse_t<span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span>
|
|
<span class="sy1"><<</span> <span class="st0">"alignof(cacheline) = "</span> <span class="sy1"><<</span> alignof<span class="br0">(</span>alignas<span class="br0">(</span><span class="nu0">64</span><span class="br0">)</span> <span class="kw4">char</span><span class="br0">[</span><span class="nu0">64</span><span class="br0">]</span><span class="br0">)</span> <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span>
|
|
<span class="sy1"><<</span> <a href="cpp-io-manip-hex.html"><span class="kw1782">std::<span class="me2">hex</span></span></a> <span class="sy1"><<</span> <a href="cpp-io-manip-showbase.html"><span class="kw1766">std::<span class="me2">showbase</span></span></a>
|
|
<span class="sy1"><<</span> <span class="st0">"&a: "</span> <span class="sy1"><<</span> <span class="sy3">&</span>a <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span>
|
|
<span class="sy1"><<</span> <span class="st0">"&b: "</span> <span class="sy1"><<</span> <span class="sy3">&</span>b <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span>
|
|
<span class="sy1"><<</span> <span class="st0">"&c: "</span> <span class="sy1"><<</span> <span class="sy3">&</span>c <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span>
|
|
<span class="sy1"><<</span> <span class="st0">"&x: "</span> <span class="sy1"><<</span> <span class="sy3">&</span>x <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span>
|
|
<span class="sy1"><<</span> <span class="st0">"&y: "</span> <span class="sy1"><<</span> <span class="sy3">&</span>y <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span>
|
|
<span class="sy1"><<</span> <span class="st0">"&z: "</span> <span class="sy1"><<</span> <span class="sy3">&</span>z <span class="sy1"><<</span> <span class="st0">'<span class="es1">\n</span>'</span><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">alignof(struct_float) = 4
|
|
sizeof(sse_t) = 32
|
|
alignof(sse_t) = 32
|
|
alignof(cacheline) = 64
|
|
&a: 0x7fffcec89930
|
|
&b: 0x7fffcec89940
|
|
&c: 0x7fffcec89950
|
|
&x: 0x7fffcec89960
|
|
&y: 0x7fffcec89980
|
|
&z: 0x7fffcec899a0</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<table class="t-dsc-begin">
|
|
<tr class="t-dsc">
|
|
<td><a href="cpp-language-alignof.html"><code>alignof</code> 运算符</a><span class="t-mark-rev t-since-cxx11">(C++11)</span></td>
|
|
<td>查询类型的对齐要求</td>
|
|
</tr>
|
|
<tr class="t-dsc">
|
|
<td>
|
|
<div class="t-dsc-member-div">
|
|
<div><a href="cpp-types-alignment_of.html"><span class="t-lines"><span>alignment_of</span></span></a></div>
|
|
<div><span class="t-lines"><span><span class="t-mark-rev t-since-cxx11">(C++11)</span></span></span></div>
|
|
</div>
|
|
</td>
|
|
<td>获取类型的对齐要求<br />
|
|
<span class="t-mark">(类模板)</span></td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|