3

次のような数千行のコードを持つチームに参加しました。

int x = 0; 
x=something(); 
short y=x; 
doSomethingImportantWith(y); 

コンパイラは、「XX ビット型の値を "short" に変換すると切り捨てが発生する」という適切な警告を出します。切り捨てが実際に発生するケースはないと言われたことがありますが、私はそれを真剣に疑っています。

次の効果を持つ各ケースにチェックを挿入する良い方法はありますか?

if (x>short.max) printNastyError(__FILE,__LINE); 

各課題の前に?これを手動で行うと、私が使用したいよりも多くの時間と労力がかかります。また、警告を読み取り、必要なインクルードだけでなく、この内容を正しいファイルに追加するスクリプトを作成するのはやり過ぎのようです。これを行いました(またはそれに似たもの)。

私はパフォーマンス (実際には) や、これらの問題がいつ発生するかを知ること以外は気にしないので、本当に重要なものだけを修正するか、それが問題であることを経営陣に納得させることができます。

4

2 に答える 2

5

次の醜いハックでコンパイルして実行してみてください。

#include <limits>
#include <cstdlib>

template<class T>
struct IntWrapper
{
    T value;

    template<class U>
    IntWrapper(U u) {
        if(u > std::numeric_limits<T>::max())
            std::abort();
        if(U(-1) < 0 && u < std::numeric_limits<T>::min()) // for signed U only
            std::abort();
        value = u;
    }

    operator T&() { return value; }
    operator T const&() const { return value; }
};

#define short IntWrapper<short>

int main() {
    int i = 1, j = 0x10000;
    short ii = i;
    short jj = j; // this aborts
}

明らかに、shortテンプレート引数として渡されるコードを壊す可能性があり、他の場合もそうなので、ビルドを壊す場所で定義を解除します。また、通常の算術演算がラッパーで機能するように、演算子のオーバーロードを追加する必要がある場合があります。

于 2013-02-06T22:00:45.087 に答える
1

おそらく、gcc のプラグインを作成して、これらの切り捨てを検出し、変換が安全であることを確認する関数を呼び出すことができます。これらのプラグインはCまたはPythonで記述できます。clang を使用したい場合は、プラグインの作成もサポートしています。

intそれを行う最も簡単な方法は、プラグインに unsafe キャストを からへshortの呼び出しに変換させることだと思います_convert_int_to_float_fail_if_data_loss(value)。このようなプラグインの書き方は、読者の演習として残しておきます。

于 2013-02-06T21:44:56.363 に答える