関数fwide

FILEストリームの入出力単位をワイド文字かバイトか設定する関数fwideについて。

実は前回のソースの

...snip
    fwide(stdout, 1);
...snip

はWindows版では設定は無視され*1、あろうが無かろうが動作した。
たとえ第二引数を1(=ワイド文字単位)にしても、
その直後にfwide(stdout, 0)を呼ぶとその戻り値は0であった。

linux版でも前回のソースであれば、あろうがなかろうが動作する。
実行時にstdoutを最初にwprintfで使うかprintfで使うかによって、
その後に使われる単位がワイド文字単位かバイト単位かが決まるようである。
なので、間違って、

#include <stdio.h>
#include <locale.h>
#include <wchar.h>

int main(void)
{
    setlocale(LC_ALL, "");
    printf("%s\n", "hello world");
    wprintf(L"%ls\n", L"こんにちは世界");
    return 0;
}

のように混在して書いてしまうと、

$ ./hello
hello world
$ 

のように二行目が出力されなかった。
printfwprintfの順序を入れ替えると、

$ ./hello
こんにちは世界
$ 

となってしまう。

...snip
    fwide(stdout, -1);
    printf("%s\n", "hello world");
    fwide(stdout, 1);
    wprintf(L"%ls\n", L"こんにちは世界");
...snip

のような書き方もできない。
一度単位が決定されてしまうとfwideは単位を変更しない。

Windows版では上の混在したソースでも二行とも問題なく出力されている。
まあ、両環境で共通したソースで済ませるという観点からは混在させずに使うべきと思う。

*1:0を返すだけで中身は未実装らしい?