1

Will it be safe to fix the warning below with casting, or could I simple change the prototype to return a u_char instead?

warning: returning 'u_char [256]' from a function with result type 'char *' converts between pointers to integer types with different sign [-Wpointer-sign]

char   * whatever(unsigned char *text)
{
        static u_char retval[256];
        int pos = 0;

        *retval = 0;
        if (!text)
                return retval;

        for (; *text && (pos < 254); text++, pos++) {
                if (*text < 32) {
                        retval[pos++] = '^';
                        retval[pos] = *text + 64;
                } else if (*text == 127) {
                        retval[pos++] = '^';
                        retval[pos] = '?';
                } else
                        retval[pos] = *text;
        }

        retval[pos] = 0;
        return retval;
}

I'm open to other possibilities as well.

4

3 に答える 3

2

もちろん、データが符号なしであると考える場合は、戻り値の型を変更する必要があります。

あなたのコードは、一般に、ASCII 値に基づいて文字に関する仮定をハードコードしているように見えるため、少し怖く見えます。これは私がお勧めするものではありません isprint()。文字を検査するポータブルな方法については、関数とその友達を参照してください。また、テキストは通常const char *​​、 ではなくであると想定されますconst unsigned char *

最後に、もちろん、バッファーへのポインターを返すことも少し危険な場合 staticがあります。コードはスレッドセーフではなく、複数の呼び出しが行われた場合、戻り値を外部から追跡し、後続の呼び出しによって上書きされるタイミングを認識するのは困難です。 .

于 2012-09-24T07:55:32.913 に答える
1

あなたの関数は入力に を受け取るので、関数の意図された目的の一部が から に変換することでない限り、それが出力unsigned char*に戻るのは合理的だと思われます。それが目的の一部である場合は、の配列ではなく、の配列にする必要があります。unsigned char*unsigned charcharretvalcharu_char

unsigned charからto への変換はchar、2 の補数の実装 (ほぼすべて) ではノーオペレーションである可能性があります。しかし、2 の補数であっても、実際にはそうであるとは限りません。(通常は 127)より大きい値の場合CHAR_MAX、変換でビット パターンを変更したり、信号を生成したりすることができます。unsigned charからto への変換がノーオペレーションchar ではない(ほぼどれも)実装では、 from からunsigned char*to へのキャストchar*は安全ではないため、警告が表示されます。

つまり、警告は、関数が扱う文字の種類を決定 (および文書化) する必要があることを示しています。キャストでその決定を回避しないでください。

于 2012-09-24T08:11:45.917 に答える
0

char*andを交換可能として扱う数百万行のコードがありますがunsigned char*、C 標準ではそれらが交換可能であるとは規定されていません。それが「安全」であるかどうかは、言葉の意味によって異なります...現在存在しない適合する実装の1つにコードを移植する可能性があると思われる場合、または交換できない場合、またはC標準に準拠していないものはハードドライブを一掃する可能性があるという衒学に同意してください。

しかし、適切にタイプ セーフなコードを記述する方がはるかに優れた方法であり、その場合、問題は発生しません。言い換えれば、「安全ではない」という理由でキャストを避けないでください。コーディングの慣行が悪いため、キャストを避けてください。そして悪い点の 1 つは、どのキャストでもバグを隠すことができるということですchar*。コンパイラがそれについてあなたに話さないようにします。型と型安全性は、バグを早期にキャッチすることでバグを回避するための強力なツールです...コンパイル時に。unsigned char*intint*

于 2012-09-24T08:57:25.003 に答える