Shift_JISに対応したコンパイラが円記号をバックスラッシュとみなすのは規格に適合していますか


Shift_JISには(いわゆる半角の)バックスラッシュ記号は存在せず、  
ASCIIにおいてバックスラッシュの割り当てられたコード位置に円記号が存在します。  
Shift_JISでエンコードされたソースコードに対応したC/C++コンパイラは、  
私の知る限りいずれもこの円記号をバックスラッシュと同一視して解釈しますが、  
これは規格に適合した動作でしょうか。

例えば `"¥n"` とあった場合、これは「円記号とn」として解釈されるべきであって、  
ラインフィードとして解釈するのは規格上正しくないのではないかと疑問に思いました。  
規格に合致させるのであれば、バックスラッシュが存在しないShift_JISにおいては、  
代替としてトライグラフ `??/` のシーケンスのみがバックスラッシュとして解釈されるのが  
正しいのではないのでしょうか。

それともISOやJISなどの規格で、ASCIIのバックスラッシュと同一のコード位置にある記号は  
バックスラッシュとして解釈する、というような規定でも存在するのでしょうか。  
コンパイラの実装や慣例ではなく、規格を厳密に解釈した場合の回答を頂きたいです。




> Shift_JISでエンコードされたソースコードに対応したC/C++コンパイラは、  
>  私の知る限りいずれもこの円記号をバックスラッシュと同一視して解釈しますが、

ソースファイルの文字コードを指定していないのではないでしょうか？  
超有名なGCCではちゃんと(?)円記号と解釈されているようで、バックスラッシュを意図した個所でコンパイルエラーになります。

[code]

    #include <stdio.h>
    
    int main()
    {
        printf("表が怖い\n能が震える\n");
        return 0;
    }
    
[/code]

CP932：

[code]

    # gcc -Wall -finput-charset=cp932 charset.c
    
    # ./a.exe
    表が怖い
    能が震える
    
[/code]

Shift_JIS：

[code]

    # gcc -Wall -finput-charset=shift_jis charset.c
    /usr/include/sys/features.h:38:4: エラー: expected identifier or ‘(’ before numeric constant
      ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
        ^
    In file included from /usr/include/sys/config.h:5:0,
                     from /usr/include/_ansi.h:16,
                     from /usr/include/stdio.h:29,
                     from charset.c:1:
    （以降エラーメッセージが続く）
    
[/code]

エラー箇所：

[code]

    #  define __GNUC_PREREQ(maj, min) \
        ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
    
[/code]

* * *

（追記）  
`printf()`の動作を確認するために`<stdio.h>`のインクルードをやめてみました。

[code]

    //#include <stdio.h>
    int printf(const char *format, ...);
    
    int main()
    {
        printf("表が怖い\n能が震える\n");
        printf("表が怖い??/n能が震える??/n");
        return 0;
    }
    
[/code]

[code]

    # gcc -Wall -finput-charset=shift_jis -trigraphs charset.c
    charset.c: 関数 ‘main’ 内:
    charset.c:7:22: 警告: トライグラフ ??/ は \ に変換されました [-Wtrigraphs]
      printf(" \   |  ??/n \   k    ??/n");
     ^
    charset.c:7:39: 警告: トライグラフ ??/ は \ に変換されました [-Wtrigraphs]
    
    # ./a.exe 
    表が怖い¥n能が震える¥n表が怖い
    能が震える
    
[/code]

