web-dev-qa-db-ja.com

エイリアシング2-Dアレイ時のSTRLENの予期せぬ最適化

これが私のコードです:

#include <string.h>
#include <stdio.h>

typedef char BUF[8];

typedef struct
{
    BUF b[23];
} S;

S s;

int main()
{
    int n;

    memcpy(&s, "1234567812345678", 17);

    n = strlen((char *)&s.b) / sizeof(BUF);
    printf("%d\n", n);

    n = strlen((char *)&s) / sizeof(BUF);
    printf("%d\n", n);
}

-O0を除く最適化レベルでGCC 8.3.0または8.2.1を使用すると、0 2が期待されていたときに2 2が出力されます。コンパイラは、strlenb[0]に制限されていることを決定し、したがって、分割されている値を等しくしたり超えることはできません。

これは私のコードやコンパイラのバグのバグですか?

これは明確に綴られていませんが、ポインターの出所の主流の解釈は、Xの主流の解釈が、コード(char *)&XXの全体を繰り返すことができるポインターを生成する必要があることでした。 X内部構造としてサブアレイを持つことが起こります。

(ボーナス質問、この特定の最適化をオフにするGCCフラグはありますか?)

36
M.M

あなたが構造体を定義した方法は私が最初に私を混同しました。誰かが関数に渡しようとした場合、彼らは彼らが額を通過しようとしているが、実際には参照によって通過すると思うかもしれません。スタイルに関係なく、そのようなタイプを作成する必要がある場合は、次のようにします。

//typedef char BUF[8];

//do it this way instead
typedef struct
{
    char x[8];
} BUF;

typedef struct
{
    BUF b[23];
} S;
 _

それをその方法で定義した場合は、どちらかの方法で期待値を返します。それを見る ここ

0
PiMaker0