CS+のコード生成ツールが生成するポインタ変数でvolatile修飾子の記述位置がおかしいものがあるように思います

藤田様の別スレッドに便乗なのですが、CS+のRL78のコード生成ツールが生成するuart通信機能のポインタ変数でvolatile修飾子の記述位置がおかしいものがあるように思います。具体的な変数名で言うと、gp_uart0_tx_addressとgp_uart0_rx_addressです。(CS+ for CC V5.00.00のコード生成機能で確認しました。)

コード生成ツールが生成した変数宣言は以下の通りです。

volatile uint8_t * gp_uart0_tx_address;         /* uart0 send buffer address */

volatile uint8_t * gp_uart0_rx_address;         /* uart0 receive buffer address */

ところが、以下の画面コピーの赤枠の箇所の通り、割り込みルーチン内で変更されるのはgp_uart0_tx_addressやgp_uart0_rx_addressの変数自身ですので以下の変数宣言が正しい気がします。

uint8_t * volatile gp_uart0_tx_address;         /* uart0 send buffer address */

uint8_t * volatile gp_uart0_rx_address;         /* uart0 receive buffer address */

試しに型修飾子の作用の仕方がvolatileと同様なconst(型修飾子の作用自体(機能)としては対義語的になる)で試してみると、変数自身に作用したのは以下の画面コピーのように橙枠の方でしたので、volatileも変数自身に作用させる場合には同様である筈です。

Parents
  • >NULL は何のオブジェクトも指しませんが、逆に、何かのオブジェクトを指すポインタは NULL でないことは確定的です。前段の hogehoge の指す先をアクセスした以降では hogehoge の値は NULL ではないということで、無限ループとなります。

      NULL だったら関数を抜けると言う判断をどこかでしているのなら分かります。
     しかし、そんな事はしていないよね。
      NULL かどうか判断して、「NULLでした」と表示するプログラムは作れないと言うこと?
     NULLをどう使うかはプログラマーしだいだと思います。printfだと0x00の前まで送ると言う仕様だから、それに従うしか無い。
     しかし自分で作った関数で、文字列の先頭アドレスと転送バイト数を指定すれば0x00の所で止める必要も無いわけです。
     言いたいことは、「NULLだったらエラーにしなくてはならず、NULLを使ってはいけません」と言う規則がある訳でも無いだろうと言う事です。

     こういう所では、よくバトルになったりするけれど、攻撃している訳じゃないですよ。
     コンパイルの動作がおかしいんじゃないかと言う話です。
  • >  NULL だったら関数を抜けると言う判断をどこかでしているのなら分かります。

    > しかし、そんな事はしていないよね。

    明示的に NULL チェックを行い、ポインタの値が NULL である可能性があることをコンパイラに伝えれば NULL だった場合は安全に関数を抜けるコードを吐きますよ。

    $ cat -n hoge.c
         1  void hoge(void)
         2  {
         3      extern volatile int* hogehoge;
         4      if (hogehoge) {
         5          while (*hogehoge) {
         6              ;
         7          }
         8      }
         9      while (hogehoge) {
        10          ;
        11      }
        12  }
    
    $ gcc -Wall -W -S -O2 hoge.c -o -
            .text
    hoge:
            movq    .refptr.hogehoge(%rip), %rax
            movq    (%rax), %rdx
            testq   %rdx, %rdx
            je      .L1
    .L5:
            movl    (%rdx), %eax
            testl   %eax, %eax
            jne     .L5
    .L4:
            jmp     .L4
    .L1:
            rep ret
    
    $
    
Reply
  • >  NULL だったら関数を抜けると言う判断をどこかでしているのなら分かります。

    > しかし、そんな事はしていないよね。

    明示的に NULL チェックを行い、ポインタの値が NULL である可能性があることをコンパイラに伝えれば NULL だった場合は安全に関数を抜けるコードを吐きますよ。

    $ cat -n hoge.c
         1  void hoge(void)
         2  {
         3      extern volatile int* hogehoge;
         4      if (hogehoge) {
         5          while (*hogehoge) {
         6              ;
         7          }
         8      }
         9      while (hogehoge) {
        10          ;
        11      }
        12  }
    
    $ gcc -Wall -W -S -O2 hoge.c -o -
            .text
    hoge:
            movq    .refptr.hogehoge(%rip), %rax
            movq    (%rax), %rdx
            testq   %rdx, %rdx
            je      .L1
    .L5:
            movl    (%rdx), %eax
            testl   %eax, %eax
            jne     .L5
    .L4:
            jmp     .L4
    .L1:
            rep ret
    
    $
    
Children
No Data