「C言語/データ型と変数の高度な話題」の版間の差分
削除された内容 追加された内容
タグ: 2017年版ソースエディター |
→型修飾子: +_Atomic タグ: 2017年版ソースエディター |
||
576 行
== 型修飾子 ==
型修飾子( ''Type qualifiers'' )は次のいずれかの組み合わせで
{|class="wikitable"
|-
!型修飾子!!意味
|-
|[[#const|const]]
|初期化以降の代入を禁止します。
|-
|[[#restrict|restrict]]
|aliasが存在しないと仮定した最適化を許します。
|-
|[[#volatile|volatile]]
|未知の方法でインスタンスが書き換えられうる事を示し、最適化を抑制します。
|-
|[[#_Atomic|_Atomic]]
|不可分操作を提供します。
|}
=== const ===
const修飾型をもったオブジェクトは初期化以外で変更不可能とな
つまり、そのオブジェクトを定数として扱うことができ、プログラム中で誤って変更するのを防ぐことができます。
<ref name="型修飾子">『JISX3010:2003』p.79「6.7.3 型修飾子」</ref>
<syntaxhighlight lang="C">
//例 constの誤った使用例
//※このプログラムはコンパイルエラーとな
int main(void)
607 ⟶ 611行目:
=== restrict ===
restrictとは、ポインタに用いる型修飾子であり、そのポインタが指す先を、同一関数・ブロック内の別のポインタが指さないという情報をコンパイラに伝え、コンパイラの最適化を促進することができます。
▲restrict型修飾子を付けても付けなくても、目に見える動作は変わらない。
<ref name="型修飾子"/>
620 ⟶ 622行目:
void *memmove(void *s1, const void *s2, size_t n);
</syntaxhighlight>
これら2つの関数は、どちらもs2をs1にn文字コピーしますが、memcpyは領域の重なり合わないオブジェクト間でコピーする必要があり、▼
▲memcpyは領域の重なり合わないオブジェクト間でコピーする必要があり、
▲そのためrestrict型修飾子を用いることができる。
=== volatile ===
volatileとは、変数がコンパイラに未知の方法で変更され、又はその他の未知の副作用を持つことをコンパイラに伝え、コンパイラの最適化を抑制する型修飾子です。
volatile宣言は、メモリ上に割り付けられた入出力ポートに相当するオブジェクト、又は非同期の割り込みメカニズムでアクセスされるオブジェクトを記述するために使用されることができます<ref name="型修飾子"/>
つまり、割り込み処理や他のスレッドで変数が変更される可能性がある場合や、特定のプロシージャでレジスタを設定する必要があるが一見冗長に見える場合などにvolatileを指定することで、コンパイラの最適化による問題を回避することができます<ref>『職業としてのプログラミング volatileで最適化を抑制する』http://proger.blog10.fc2.com/blog-entry-20.html</ref>。
== _Atomic ==
C11 6.7.2.4 Atomic type specifiers
6.7.2.4 原子型指定子
; 構文
:; atomic-type-specifier:
:: _Atomic ( type-name )
; 制約事項
: 実装が原子型をサポートしていない場合、原子型指定子( ''Atomic type specifiers'' )を使用してはならない(6.10.8.3 Conditional feature macros 参照)。
: 原子型指定子の型名は、配列型、関数型、原子型、または修飾型を参照してはならない。
; セマンティクス
: 原子型に関連するプロパティは、lvalues(左辺値)である式に対してのみ意味を持ちます。
: キーワード_Atomicの直後に左括弧がある場合は、型修飾子ではなく、(型名を持つ)型指定子として解釈されます。
== フォーマット指定子 ==
|