CS+ 空き領域の確保について

64Byteピッタリの構造体を作成したい場合ですが

typedef struct{
char cmd;
char len;
char str;
char pad[sizeof(USB_CMD)-offsetof(USB_CMD,pad)];
} USB_CMD;

のようにするとCS+で

(E) E0520020 usb_cmd.h(18):E0520020:Identifier "offsetof" is undefined usb_cmd.h 18 gen.mtpj

(E) E0520020 usb_cmd.h(18):E0520020:Identifier "USB_CMD" is undefined usb_cmd.h 18 gen.mtpj

(E) E0520020 usb_cmd.h(18):E0520020:Identifier "pad" is undefined usb_cmd.h 18 gen.mtpj

(E) E0520059 usb_cmd.h(18):E0520059:Function call is not allowed in a constant expression usb_cmd.h 18 gen.mtpj

等が発生するのです、(当たり前かな)ここでpad部分でこのUSB_CMDを64Byteに調整したいのですが

union等使用する方法もありますが、文字が多くなるため、このような方法でできないかと思っています

良い方法があるのでしょうか?

Parents
  • > 64Byteピッタリの構造体を作成したい場合ですが

    typedef union {
        struct{
            char cmd;
            char len;
            char str;
        };
        char pad[64 * 1024];
    } USB_CMD;
    
    
  • fujita nozomuさん
    ありがとうございます、おっしゃるとうりにいたしましたところ、できました
    typedef union {
    struct{
    char cmd;
    char len;
    char str;
    };
    char pad[64];
    } USB_CMD;
    USB_CMD usb_cmd;
    printf("%d \r",sizeof(usb_cmd) );
    結果
    64
    でした、strのサイズを変更してもUSB_CMD自体のサイズは一定でした、
    ありがとうございました解決です。
    ところで64Byte以上になったら、コンパイラエラーとか警告とかは無理ですよね、
  • わわいです
    構造体の定義の中でoffsetofマクロ使ってるところで、ここでは使えない、とエラーが出てますな。
    そりゃまだ定義されていない構造体を使おうとしてもムリムリですね。
    そのうえ、定義されてない構造体のsizeofも無理だし、配列のサイズは定数じゃないとだめって事になってるのでいろいろ無理です。
    まあ、考えてみればアタリマエのことですが。
  • わわいさん
    「構造体の定義の中でoffsetofマクロ使ってる」おもろいことやってるねーて笑われますね、なんだかCS+がエラーばかり言って来るので大変で、自分でもなにかおかしいんじゃないかとは思ったのですが、おっしゃるとうりです。
  • お世話になっております、
    64Byte以上になったら、コンパイラエラーとか警告とか出せるようにしたいのですが
    typedef union {
    struct{
    char cmd;
    char len;
    char str[62];
    };
    char pad[64];
    } USB_CMD;
    #if (sizeof(USB_CMD) > 64)
    error 64 USB_CMD
    #endif
    usb_cmd.h(18):E0520059:Function call is not allowed in a constant expression
    エラーになります、教えていただけませんでしょうか?
  • わわいです
    #if ってのは、プリプロセッサで処理されます
    だもんで、構造体やら共用体はその段階では解析されてません。
    ここには、定数だけしか使用できません。
    なので、この場合は実行時エラーとするしかないかとおもわれます。

    C言語ソースをビルドすると、以下の段階を経て実行イメージを生成します
    #ごくごく簡単な説明です。。

    Cソース>プリプロセッサ>コンパイラ>アセンブラ>リンカ>実行イメージ
    ・プリプロセッサ
     #if やら #define を展開、コメントを削除するだけ
    ・コンパイラ
     コードをアセンブルコードに翻訳
    ・アセンブラ
     アセンブルコードから機械語(オブジェクトファイル)に翻訳
    ・リンカ
     複数のオブジェクトファイルをセクションごとにアドレス配置、バイナリイメージ(実行イメージ)を生成

    ということで、#if でsizeofを使うのはムリゲーなのはわかるとおもいます
  • ビルド時にエラー検出できなくても、起動時にチェックするという手もあります。
  • わわいさん
    「#if ってのは、プリプロセッサで処理されますだもんで、構造体やら共用体はその段階では解析されてません。」なるほど、sizeof(USB_CMD) 等は使用できないですか?なにか良い方法があって欲しいものですが。
  • Higetakaさん
    現状はおっしゃるように、下記のようにやっていまして
    //デバッグ用表示(起動時に表示される)
    printf("MODE_DATA %d 残 %d Byte\r",sizeof(MODE_DATA),sizeof(MODE_DATA)-sizeof(result_data[0].mode.data));
    もっとスマートな方法がないかと思っております。
  • わわいです
    まー私がするなら、
    typedef union {
     struct{
      char cmd;
      char len;
      char str[1];
     };
     char pad[64];
    } USB_CMD;

    #define STR_SIZE (sizeof(USB_CMD)-offsetof(USB_CMD,str)) // strのサイズ

    とでもしておきますねー
    サイズのチェック、ってのは一度確認してしまえば不要なものですし
  • わわいさん
    回答ありがとうございます、STR_SIZEで確認できると思うのですが、USB_CMDというのはUSBの最大パケットサイズでして、このstrという部分が曲者で色々好きなように再定義して使用するようにしたいのですが、どれぐらい使用しているのか、もしくははみ出したらコンパイラーがエラーにしてくれればこれはすごい便利だと思いました、問題というのがこのpadですが危なそうなら1000とでもしておけばよいじゃないの、ということに着きますが、コンパイラーのプリプロセッサー機能でなんとかなればすばらしいなーと。
Reply
  • わわいさん
    回答ありがとうございます、STR_SIZEで確認できると思うのですが、USB_CMDというのはUSBの最大パケットサイズでして、このstrという部分が曲者で色々好きなように再定義して使用するようにしたいのですが、どれぐらい使用しているのか、もしくははみ出したらコンパイラーがエラーにしてくれればこれはすごい便利だと思いました、問題というのがこのpadですが危なそうなら1000とでもしておけばよいじゃないの、ということに着きますが、コンパイラーのプリプロセッサー機能でなんとかなればすばらしいなーと。
Children
No Data