C 語言裡面的 ??! 符號

Hacker News Daily 上看到這個奇怪的知識:「What does the ??!??! operator do in C? (stackoverflow.com)」,原文在 Stack Overflow 上:「What does the ??!??! operator do in C?」。

這是 trigraph,在 C89 就有了,從 Rationale for International Standard—Programming Languages—C 這邊的 5.2.1.1 可以看到 trigraph 的歷史原因:

Trigraph sequences were introduced in C89 as alternate spellings of some characters to allow the implementation of C in character sets which do not provide a sufficient number of non-alphabetic graphics

而且是強制要求實做:

Implementations are required to support these alternate spellings, even if the character set in use is ASCII, in order to allow transportation of code from systems which must use the trigraphs. AMD1 also added digraphs (see §6.4.6 and §MSE.4).

其中遇到的問題就是當年得決定 C 可以用的 charset,得考慮到很多不同機器 charset 相容性的問題:

The C89 Committee faced a serious problem in trying to define a character set for C. Not all of the character sets in general use have the right number of characters, nor do they support the graphical symbols that C users expect to see. For instance, many character sets for languages other than English resemble ASCII except that codes used for graphic characters in ASCII are instead used for alphabetic characters or diacritical marks. C relies upon a richer set of graphic characters than most other programming languages, so the representation of programs in character sets other than ASCII is a greater problem than for most other programming languages.

然後就使用了 ISO/IEC 646 這個標準 (要記得 Unicode 1.0.0 是 1991 年才出現):

The solution is an internationally agreed-upon repertoire in terms of which an international representation of C can be defined. ISO has defined such a standard, ISO/IEC 646, which describes an invariant subset of ASCII.

The characters in the ASCII repertoire used by C and absent from the ISO/IEC 646 invariant repertoire are:

[ ] { } \ | ~ ^

後面就是定義 ?? 當作 escape digraph。

算是一個歷史產物,現在不太需要用到了...

C 語言的 extern 與 static...

把十年多的 BBS source code porting 到 Ubuntu 上,被迫要用 GCC 4.6 而一路找出來的...

在 BBS 內有這樣的資料結構要處理:

typedef struct p {
    struct p *pointer;
} P;

static P p1 = { &p2 };
static P p2 = { &p1 };

兩個要互指,但在指定 p1 時 p2 還沒有被定義,所以要用 extern 先宣告:

typedef struct p {
    struct p *pointer;
} P;

extern P p2;

static P p1 = { &p2 };
static P p2 = { &p1 };

這個語法在舊版的 GCC 沒問題 (3.4),但在新版的 GCC 4.6 上不接受這個寫法,會抱怨後面的 p2 實際在宣告是 static,與前面的 extern non-static 不符。

後來在 Stack Overflow 上找到「static extern vs extern static」這篇說明,要先定義 static 再定義 extern:

static P p2;
extern P p2;

這樣寫的原因在原文的下方有說明,所以是 C99 定義的關係?

筆記型電腦的充電器單一化...

Slashdot 上看到「Standardized Laptop Charger Approved By IEC」這篇。

2011 年年初的「歐盟強制使用 Micro USB 做為手機充電介面」後,IEC 這次宣佈要標準化筆電的充電器:「Major milestone: single charger for notebook computers will significantly reduce e-waste」。

目前的進度在最後一段可以看到:

IEC Technical Specification 62700: DC Power supply for notebook computer, will be available in early 2014.

不過... 筆電充電器這塊如果要做的好用,不會卡到蘋果的專利嗎?

關於 ISO/IEC 27001...

昨天 (過十二點了) 跟兔子吃飯提到 ISO/IEC 27001,果然有些數字當場都記錯了...

www.iso27001certificates.com/Register%20Search.htm 這邊有資料可以看每個國家通過的張數,另外在 www.iso27001certificates.com/certification_directory.htm 則可以查到有哪些單位負責認證與稽核。

2012 年八月的現在,台灣通過 461 張 (這幾年竄起的),中國 393 張,美國與加拿大加起來 115 張 (之前看的時候還是兩位數?)...

至於這些數字要怎麼解讀,就是個人的想法了 :p