2012-12-17 35 views
0

cygwin的GCC 4.5.3爲什麼燒焦<< and char >>中間結果詮釋

我試圖確定在C++中的各種計算中使用的中間結果。關於「字符」我得到的follwoing結果(x是一個字符):

x op y is of type char if y is a char/unsigned char 
x op y is of type y otherwise except if op is left/right shift 

爲左/右移位,中間結果的類型是「INT」,這是違背所有其他計算的。這是標準實施嗎?

這裏是(通過它不要高興得太早)使用的代碼:

# include <iostream> 
# include <iomanip> 
# include <typeinfo> 
# include "cstdio" 
# include <cstdlib> 

using namespace std; 

typedef unsigned char UCHAR; 
typedef unsigned short USHORT; 
typedef unsigned int INT; 
typedef unsigned long ULONG; 
string find(type_info* info) { 
    struct type { 
     type_info* typeInfo; 
     string  name; 
    }; 
    int i; 
    static type types[] = { {const_cast<type_info*>(&typeid(bool)), " BOOL" } 
         , {const_cast<type_info*>(&typeid(char)), " CHAR" } 
         , {const_cast<type_info*>(&typeid(UCHAR)), " UCHAR" } 
         , {const_cast<type_info*>(&typeid(short)), " SHORT" } 
         , {const_cast<type_info*>(&typeid(USHORT)), " USHORT"} 
         , {const_cast<type_info*>(&typeid(int)), " INT" } 
         , {const_cast<type_info*>(&typeid(uint)), " UINT" } 
         , {const_cast<type_info*>(&typeid(long)), " LONG" } 
         , {const_cast<type_info*>(&typeid(ULONG)), " ULONG" } 
         }; 
    for(i = 0; i < sizeof(types)/sizeof(types[0]); i++) 
     if (types[i].typeInfo == info) break; 
    if (i >= sizeof(types)/sizeof(types[0])) return " NOT FOUND"; 
    return types[i].name; 
} 
void func0(char x) { 
    ios_base::fmtflags ioFlags = cout.flags(); 
    string info = find(const_cast<type_info*>(&typeid(x))); 
    char save = x; 
    cout << "func0(char " << (long)x << ')' << endl; 
    cout << "!x " << setw(12) << (!x) << " 0x" << setw(8) << setfill('0') << hex << (!x) << find(const_cast<type_info*>(&typeid(!x))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "~x " << setw(12) << (~x) << " 0x" << setw(8) << setfill('0') << hex << (~x) << find(const_cast<type_info*>(&typeid(~x))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "+x " << setw(12) << (+x) << " 0x" << setw(8) << setfill('0') << hex << (+x) << find(const_cast<type_info*>(&typeid(+x))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "-x " << setw(12) << (-x) << " 0x" << setw(8) << setfill('0') << hex << (-x) << find(const_cast<type_info*>(&typeid(-x))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "++x " << setw(12) << (long)(++x) << " 0x" << setw(8) << setfill('0') << hex << (++x) << find(const_cast<type_info*>(&typeid(++x))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); x = save; 
    cout << "--x " << setw(12) << (long)(--x) << " 0x" << setw(8) << setfill('0') << hex << (--x) << find(const_cast<type_info*>(&typeid(--x))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); x = save; 
    cout << "x++ " << setw(12) << (long)(x++) << " 0x" << setw(8) << setfill('0') << hex << (x++) << find(const_cast<type_info*>(&typeid(x++))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); x = save; 
    cout << "x-- " << setw(12) << (long)(x--) << " 0x" << setw(8) << setfill('0') << hex << (x--) << find(const_cast<type_info*>(&typeid(x--))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << endl; 

} 
void func1(char x, char y) { 
    ios_base::fmtflags ioFlags = cout.flags(); 
    cout << "func1(char " << (signed long)x << ", char " << (unsigned long)y << ')' << endl; 
    cout << "x + y " << setw(12) << (x + y) << " 0x" << setw(8) << setfill('0') << hex << (x + y) << find(const_cast<type_info*>(&typeid(x + y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x - y " << setw(12) << (x - y) << " 0x" << setw(8) << setfill('0') << hex << (x - y) << find(const_cast<type_info*>(&typeid(x - y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x * y " << setw(12) << (x * y) << " 0x" << setw(8) << setfill('0') << hex << (x * y) << find(const_cast<type_info*>(&typeid(x * y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    if (y == 0) { 
     cout << "x/y " << x << "/0" << endl; 
    } else { 
     cout << "x/y " << setw(12) << (x/y) << " 0x" << setw(8) << setfill('0') << hex << (x/y) << find(const_cast<type_info*>(&typeid(x/y))) << endl; 
    } 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x % y " << setw(12) << (x & y) << " 0x" << setw(8) << setfill('0') << hex << (x & y) << find(const_cast<type_info*>(&typeid(x & y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x << y " << setw(12) << (x << y) << " 0x" << setw(8) << setfill('0') << hex << (x << y) << find(const_cast<type_info*>(&typeid(x << y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x >> y " << setw(12) << (x >> y) << " 0x" << setw(8) << setfill('0') << hex << (x >> y) << find(const_cast<type_info*>(&typeid(x >> y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x & y " << setw(12) << (x & y) << " 0x" << setw(8) << setfill('0') << hex << (x & y) << find(const_cast<type_info*>(&typeid(x & y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x | y " << setw(12) << (x | y) << " 0x" << setw(8) << setfill('0') << hex << (x | y) << find(const_cast<type_info*>(&typeid(x | y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x^x " << setw(12) << (x^y) << " 0x" << setw(8) << setfill('0') << hex << (x^y) << find(const_cast<type_info*>(&typeid(x^y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << endl; 
} 
void func1(char x, unsigned char y) { 
    ios_base::fmtflags ioFlags = cout.flags(); 
    cout << "func1(char " << (signed long)x << ", uchar " << (unsigned long)y << ')' << endl; 
    cout << "x + y " << setw(12) << (x + y) << " 0x" << setw(8) << setfill('0') << hex << (x + y) << find(const_cast<type_info*>(&typeid(x + y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x - y " << setw(12) << (x - y) << " 0x" << setw(8) << setfill('0') << hex << (x - y) << find(const_cast<type_info*>(&typeid(x - y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x * y " << setw(12) << (x * y) << " 0x" << setw(8) << setfill('0') << hex << (x * y) << find(const_cast<type_info*>(&typeid(x * y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    if (y == 0) { 
     cout << "x/y " << x << "/0" << endl; 
    } else { 
     cout << "x/y " << setw(12) << (x/y) << " 0x" << setw(8) << setfill('0') << hex << (x/y) << find(const_cast<type_info*>(&typeid(x/y))) << endl; 
    } 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x % y " << setw(12) << (x & y) << " 0x" << setw(8) << setfill('0') << hex << (x & y) << find(const_cast<type_info*>(&typeid(x & y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x << y " << setw(12) << (x << y) << " 0x" << setw(8) << setfill('0') << hex << (x << y) << find(const_cast<type_info*>(&typeid(x << y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x >> y " << setw(12) << (x >> y) << " 0x" << setw(8) << setfill('0') << hex << (x >> y) << find(const_cast<type_info*>(&typeid(x >> y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x & y " << setw(12) << (x & y) << " 0x" << setw(8) << setfill('0') << hex << (x & y) << find(const_cast<type_info*>(&typeid(x & y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x | y " << setw(12) << (x | y) << " 0x" << setw(8) << setfill('0') << hex << (x | y) << find(const_cast<type_info*>(&typeid(x | y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x^x " << setw(12) << (x^y) << " 0x" << setw(8) << setfill('0') << hex << (x^y) << find(const_cast<type_info*>(&typeid(x^y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << endl; 
} 
void func1(char x, unsigned long y) { 
    ios_base::fmtflags ioFlags = cout.flags(); 
    cout << "func1(char " << (signed long)x << ", ulong " << y << ')' << endl; 
    cout << "x + y " << setw(12) << (x + y) << " 0x" << setw(8) << setfill('0') << hex << (x + y) << find(const_cast<type_info*>(&typeid(x + y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x - y " << setw(12) << (x - y) << " 0x" << setw(8) << setfill('0') << hex << (x - y) << find(const_cast<type_info*>(&typeid(x - y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x * y " << setw(12) << (x * y) << " 0x" << setw(8) << setfill('0') << hex << (x * y) << find(const_cast<type_info*>(&typeid(x * y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    if (y == 0) { 
     cout << "x/y " << x << "/0" << endl; 
    } else { 
     cout << "x/y " << setw(12) << (x/y) << " 0x" << setw(8) << setfill('0') << hex << (x/y) << find(const_cast<type_info*>(&typeid(x/y))) << endl; 
    } 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x % y " << setw(12) << (x & y) << " 0x" << setw(8) << setfill('0') << hex << (x & y) << find(const_cast<type_info*>(&typeid(x & y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x << y " << setw(12) << (x << y) << " 0x" << setw(8) << setfill('0') << hex << (x << y) << find(const_cast<type_info*>(&typeid(x << y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x >> y " << setw(12) << (x >> y) << " 0x" << setw(8) << setfill('0') << hex << (x >> y) << find(const_cast<type_info*>(&typeid(x >> y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x & y " << setw(12) << (x & y) << " 0x" << setw(8) << setfill('0') << hex << (x & y) << find(const_cast<type_info*>(&typeid(x & y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x | y " << setw(12) << (x | y) << " 0x" << setw(8) << setfill('0') << hex << (x | y) << find(const_cast<type_info*>(&typeid(x | y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x^x " << setw(12) << (x^y) << " 0x" << setw(8) << setfill('0') << hex << (x^y) << find(const_cast<type_info*>(&typeid(x^y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << endl; 
} 
void func1(char x, long y) { 
    ios_base::fmtflags ioFlags = cout.flags(); 
    cout << "func1(char " << (signed long)x << ", long " << y << ')' << endl; 
    cout << "x + y " << setw(12) << (x + y) << " 0x" << setw(8) << setfill('0') << hex << (x + y) << find(const_cast<type_info*>(&typeid(x + y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x - y " << setw(12) << (x - y) << " 0x" << setw(8) << setfill('0') << hex << (x - y) << find(const_cast<type_info*>(&typeid(x - y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x * y " << setw(12) << (x * y) << " 0x" << setw(8) << setfill('0') << hex << (x * y) << find(const_cast<type_info*>(&typeid(x * y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    if (y == 0) { 
     cout << "x/y " << x << "/0" << endl; 
    } else { 
     cout << "x/y " << setw(12) << (x/y) << " 0x" << setw(8) << setfill('0') << hex << (x/y) << find(const_cast<type_info*>(&typeid(x/y))) << endl; 
    } 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x % y " << setw(12) << (x & y) << " 0x" << setw(8) << setfill('0') << hex << (x & y) << find(const_cast<type_info*>(&typeid(x & y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x << y " << setw(12) << (x << y) << " 0x" << setw(8) << setfill('0') << hex << (x << y) << find(const_cast<type_info*>(&typeid(x << y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x >> y " << setw(12) << (x >> y) << " 0x" << setw(8) << setfill('0') << hex << (x >> y) << find(const_cast<type_info*>(&typeid(x >> y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x & y " << setw(12) << (x & y) << " 0x" << setw(8) << setfill('0') << hex << (x & y) << find(const_cast<type_info*>(&typeid(x & y))) << endl; 
cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x | y " << setw(12) << (x | y) << " 0x" << setw(8) << setfill('0') << hex << (x | y) << find(const_cast<type_info*>(&typeid(x | y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << "x^x " << setw(12) << (x^y) << " 0x" << setw(8) << setfill('0') << hex << (x^y) << find(const_cast<type_info*>(&typeid(x^y))) << endl; 
    cout.flags(ioFlags); cout << setfill(' '); 
    cout << endl; 
} 

int main(int argc, char** argv) { 
    char x = -1; 
    func0((char) 1); 

    func1(x, (char) 1); 
    func1(x, (unsigned char) 1); 
    func1(x, (long) 1); 
    func1(x, (unsigned long) 1); 
    sleep(1); 
    return 0; 
} 
+3

我得到了所有'char/[unsigned] char'操作的結果類型'int',因爲它應該是(整型促銷)。 –

回答

0

通過添加以下頂部使代碼編譯後,

typedef unsigned uint; //! 
void sleep(int) {} //! 
#include <string> //! 

仍有一些正式的UB,但應該不是很重要。

結果做,然而,指示

「 X運算y是字符類型如果y是一個字符/無符號字符
X運算y是類型Y的否則除了如果op是左/右移」

你使用什麼編譯器?

你問,

「這是標準的執行? 」

那麼,不,沒有標準的實施。只有一個ISO標準。

+0

@AudreyT:我使用的cygwin的gcc 4.5.3作爲我的編譯器。我的結果與你的不同,希望如下。請原諒我在問一個「標準執行」不準確,我沒有根據ISO標準的意思的實現。這裏是我的結果: func1的(字符-1,長1) X + Y 0 00000000 LONG 說明X - Y -2 0xfffffffe LONG X * Y -1爲0xffffffff LONG 的x/y -1爲0xffffffff LONG X%Y 1 00000001 LONG X <<ý-2 0xfffffffe INT X >> Y -1爲0xffffffff INT – skidmarks

1

您的初步結論不正確。 C/C++中的所有算術運算至少(或可能是unsigned int)在大小爲int的域內執行計算。在開始任何實際計算並且結果的類型爲int之前,所有較小的操作數類型(charshort等)都被提升爲int。只有前綴和後綴版本++--才能保留其操作數的類型。

這適用於操作,如二進制+*-等。這適用於<<>>爲好。所以<<>>與其他算術運算符沒有任何區別。

您是如何得出結論的:"x op y is of type char if y is a char/unsigned char"對我而言並不是很清楚。我剛剛運行了您的代碼,並確認了預期的行爲:只有像++--這樣的操作評估爲char類型,而其他所有操作參數的評估值爲int

+0

ùmeen 「至少」 –

+0

@Cheers和第h。 Alf:是的。我補充說,「至少」的答案。謝謝。 – AnT

+0

我正在使用cygwin gcc 4.5.3。我相信你的意見。我不知道,我相信我的代碼,但結果是,預期的結果不是我所看到的。我不知道爲什麼有差異。我看着在我的代碼的「違規」的陳述,他們似乎是正確的,或者至少像其他的語句。 – skidmarks

相關問題