共有ライブラリに次の行が含まれているとします。
const char* const arr[] =
{
"one",
"two",
"three"
};
1)アプリケーションはこのライブラリにリンクして記号「arr」を使用できますか?
2)新しい要素が定義に追加された場合、バイナリ互換性は失われますか?
3)文字列リテラルの1つが変更された場合はどうですか?
4)なぜ(そうではない)?
乾杯、ルーク
共有ライブラリに次の行が含まれているとします。
const char* const arr[] =
{
"one",
"two",
"three"
};
1)アプリケーションはこのライブラリにリンクして記号「arr」を使用できますか?
2)新しい要素が定義に追加された場合、バイナリ互換性は失われますか?
3)文字列リテラルの1つが変更された場合はどうですか?
4)なぜ(そうではない)?
乾杯、ルーク
1)はい
2)いいえ
3)問題ありません
4)なぜあなたはそうではないと思いますか?
どちらの場合も、バイナリ互換性は損なわれません。
Cスタイルの配列は、配列の長さを格納したり仮定したりしないため、配列の長さを増やしても仮定が破られることはありません。
ポインタの配列があるため、文字列リテラルを変更しても、配列のメモリレイアウトにはまったく影響しません。
記号arrは、配列内の要素に関係なく、配列のベースを指します。要素の数または1つ以上の要素の値を変更できますが、arr記号は引き続き配列の先頭を指します。
ただし、アプリケーションにはarrに関する詳細情報が必要な場合があります。おそらく、アプリケーションに含まれる要素の数を知りたいと考えています。
NULLポインターでリストを終了するか、サイズをエクスポートします。
const size_t arrSize = sizeof(arr)/sizeof(char*);
1)はい、宣言されていればextern
(オブジェクトにはデフォルトで静的リンケージがあることに注意してくださいconst
;はい、直感に反します;))。
2) リンク先のコードがこの arr をどのように使用するかによって異なります。新しいエントリを外部コードに役立てたい場合は、arr
NULL で終了するか、extern const unsigned arr_size = sizeof(arr) / sizeof(arr[0])
.
3) いいですよ。配列自体は、リテラル表現へのポインターで構成されます。リテラルが変更されても、配列自体のレイアウトは変更されません。
4) いいえ、arr
リテラル表現へのポインターの連続したシーケンスであるため、それだけです。