strlen(&"123"[1]) この書き方はでエラーが出ないのが不思議です

[code]

    #include<iostream>
    #include<cstring>
    using namespace std;
    
    int main(int argc, char** argv){
        cout<<strlen(&"123"[1])<<endl;
    }
    
[/code]

> 2  
>  Enterキーを押すと、ターミナルが終了します...

この書き方でなぜエラーが出ないのか全く理解ができません  
エラーが出ないからには何かしらの理解の仕方があると思うのですがさっぱりです。  
これは、コンパイラから見てどう解釈されているのですか




混乱を避けるため 123 でなくて abc としておく

`"abc"+1` だったらわかりやすかったのかも？  
悪乗りしてみるテスト  
`1+"abc"` とか  
`&1["abc"]` とか

ここに上げた例３つは全部、元質問の `&"abc"[1]` と同じ意味です。

コンパイラがどう解釈するかを [c](/questions/tagged/c "'c' のタグが付いた質問を表示")
[c++](/questions/tagged/c%2b%2b "'c++' のタグが付いた質問を表示") 言語仕様書的に解説するなら  
\- `P[Q]` は `*(P+Q)` と解釈される  
\- 配列 (この例では文字列リテラルが文字の配列です) は容易にポインタ右辺値に成り下がる  
\- ポインタ右辺値と整数値の加算の場合 `P` と `Q` が入れ替わっても結果は同じ  
\- `&(*(P))` は `P` そのもの。つまり `&P[Q]` は `P+Q` になる  
ってとこでしょうか。




既に回答がついていますが、簡潔すぎるのではないかと思い補足的に書きます。

(1)`"123"`は、既に書いた時点で`char[]`のリテラルです。

[code]

    cout << strlen(&"123"[1]) << endl;
    
[/code]

は、次と同様です。

[code]

    char[] str = "123";
    cout << strlen(&str[1]) << endl;
    
[/code]

実際のリテラルの中身は、次のようになってます。

[code]

    str[0] : '1'
    str[1] : '2'
    str[2] : '3'
    str[3] : '\0'(null)
    
[/code]

(2)`"123"[1]`は、`"123"`という`char[]`リテラルの第2要素を指しています。つまり`str[1]`です。

つまり、`"123"[1]`そのものは、`str[1]`と同じなので、2文字目にある`'2'`です。

(3)`&"123"[1]`は、`&(str[1])`と同じで、`"123"`という`char[]`リテラルの第2要素のポインタ（通常は`'2'`のあるアドレス）を指しています。

(4)`strlen(&"123"[1])`は、`"123"`という`char[]`リテラルの第2要素から数えて、`'\0'`(null)が出てくるまでのcharの数なので、2（`str[1]`,`str[2]`で2つ）となります。

