C++ Primitive Type 的標準定義小記

為了寫出 robustless bugs 的程式碼,就要依照 保證 (C++ defined) 來寫 Code ,而且遇到 system-defined 的東西,必須 額外小心 地處理。

一些 Primitive Type 的最小空間保證:

  • char, wchar_t 只保證 8 bits 以上。
  • short 只保證 16 bits 以上。
  • int 只保證 16 bits 以上。
  • long 只保證 32 bits 以上。
  • longlong 只保證 64 bits 以上。
  • 關係只保證 1 = sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(longlong)

  • 所以極端情況下,有可能 char 是 64 bits 。

  • 有可能 在 64 bits 的 OS 下,你拿著 16 bits 的 int 去裝 address。要用 intptr_t 來裝,它有被 C++11, C99 定義 (C++03 沒有...),又或是 C++03 就要自已定義好可以裝得下 address 的 integer type。
    REF: http://stackoverflow.com/questions/6326338/why-when-to-use-intptr-t-for-type-casting-in-c

    intptr_t
    #include <cstdint>
    ...
    int a = 1;
    intptr_t address_of_a = &a;
    ...


    • 最好使用 size_t 來乘裝 STL Container、string 中的 size_t size() const 回傳值或是使用 size_t 來與它比較。
      for(size_t i = 0; i < a_vector.size(); ++i){
      ... 
      };
      

    char

    • 單寫一個 char ,則他的型別是 unsigned char 或是 signed char,是 system-defined
    • char 的空間初始定義是保證能夠表示 basic execution character set,簡略一點說就是只保證裝得下 ANSI,一定有有 0 ~ 127 的空間。
    • 有些系統中 char 可以表示 128~255 ,那段空間的字集叫 擴充字集,用來放一些 非標準字元,像是重音字母、表情符號等等。
    • 不要認為 char 一定可以裝負數。要用 signed char
    • 不要拿 char 去裝 128 以上的值。要用 unsigned char

    wchar_t

    • C++ 只保證 sizeof(char) <= sizeof(wchar_t) <= sizeof(long)wchar_t 也有可能跟 char 一樣都是 8 bits 。
    • wchar_t 大小是 system-defined ,Windows 是用 16bits,Linux 是用 32bits。
    • Unicode 標準指出使用 wchar_t 裝 unicode 字元並 不具有可攜性http://en.wikipedia.org/wiki/Wide_character
    • 一般推薦是使用 std::basic_string<char> + UTF-8 + encoding libraries(ICU/C++11內建) ,來乘載 unicode 字元。

    數字型別的 Overflow 行為:

    • unsigned numeric types 在 C++ 定義下,overflow 計算 不會造成 Undefined Behavior,而是有 mathematic defined模運算
    • signed numeric types 在 C++ 定義下,overflow 計算 會造成Undefined Behavior ,是因為要讓 compiler 有最佳化的空間。

    Ref: http://stackoverflow.com/questions/3948479/integer-overflow-and-undefined-behavior#3948496

    Compiler optimizes the never enterted(in non-overflow situation) part
    if(a> 0 and b > 0)
    {
        if(a+b>0)
        {
          ...
        }else{ // compiler 會最佳化掉而砍掉這段 else statement
          ... 
        }
    } 
    

    負數的有效範圍

    • C++ 沒有定義負數是 1's complement 還是 2's complement,也有可能有些系統的 CPU 不支援 2's complement ,所以你只能說 16bits signed short 的有效空間是 -32767 ~ 32767,-32768 是否存在是 system-defined。 REF: http://bytes.com/topic/c/answers/438759-range-short-int

    Boolean

    • 在 C++ 中,標準有定義 keyword truefalse ,稱之為 boolean literals
    • 在 C 中,標準沒有定義 keyword truefalse ,也沒有 boolean type 的概念,通通以 int: 1int: 0 來表示。

    C 模擬 Boolean 型別

    其他雜事小記

    • 依照標準來說,天堂的正義值也是有可能是用 signed int 存的。
    • C++ 標準沒有 longlonglong,不過 gcc 有自已的 __int128 擴充。
    • std::string 裝 utf-8 ,那麼他的 size_t std::string::length() const method 語意就不是句子的長度了,是 bytes 的個數,因為 utf-8 是變動 bytes 的 encoding。

    Reference

    Book: The C++ Programming Language 4th Edition
    Book: The C++ Primer 4/e 中文版
    C++ Standard Draft ISO/IEC 14882: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf

comments powered by Disqus