8

私の単純な C99 プロジェクトには、実装する必要があるインターフェース ( GObject interfacesを介して) を定義する外部 C ライブラリがあります。

void interface_function (const char *address, [...]);

さて、(私が書く必要がある)実装内で、別のライブラリから他の関数​​を呼び出す必要があります(そのため、それらを変更することはできません*addressconst

void some_api_function (char *address, [...]);

ここで、単純に に渡す*addresssome_api_function、コンパイラの警告が表示されます。

warning: passing argument 1 of ‘some_api_function’ discards ‘const’ qualifier from pointer target type [enabled by default]

char *次のように関数呼び出しで明示的にキャストしようとしました:

`some_api_function ((char*) address, [...]) { ... }

しかし、その後、別の警告が表示されます。

warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]

問題は、これが多くの人が取り組んでいる大規模な C プロジェクトであり、ポリシーが-Werror有効になっており、コンパイル時に警告を発するコードがメインライン ソース コードに受け入れられないことです。

インターフェイスの定義はサードパーティなので変更できませんし、外部ライブラリのAPI定義も変更できません。私はそれ*addressが外部ライブラリで変更されていないことを知っています(それはconstかもしれませんが、私が言ったようにそれを変更することはできません)

const char*また、この問題を解決するには、 intoのコピーを作成するだけでよいこともわかっていますchar *が、不要なコピー操作が必要になるため、それは適切ではありません。

では、これを行うためのエレガントまたは「正しい」方法は何ですか?

4

3 に答える 3

16

絶対的な安全のために、文字列をディープ コピーして、パフォーマンスへの影響をプロファイリングします。関数の作成者は、文字列を変更しないことを保証しません。パラメータがマークconst char*されている場合、関数によって文字列が変更されないという意味があります。

他にも選択肢があります。(void*) または巧妙なユニオン トリック (Gung Foo の回答を参照) を介してキャストしますが、どちらもプログラムの安定性を保証しません。

于 2013-10-02T07:35:54.557 に答える
8

ユニオンを使用できます。

union charunion {
   char *chr;
   const char* cchr;
} chrptrs;

chrptrs.cchr; // const char *
chrptrs.chr;  // char *
于 2013-10-02T07:36:06.733 に答える
0

警告には理由があります。Bathseheeba が言うように、宣言は関数が値を変更しないことを保証するものではないため、何をしているのかを知っている場合、つまり、関数が「アドレス」が指す値を変更しようとしないことを知っている場合は、これを行うことによる警告:

void interface_function (const char *address, [...])
{
    char *chrptr=(char *)address;
    [...]
    some_api_function (chrptr, [...]);
    [...]
 }

編集:あなたがBathsheebaの提案に従うとコメントする前に、私は答えていました. 良い選択。

于 2013-10-02T09:12:50.073 に答える