RX62で__VA_ARGS_

初めて質問させていただきます。

mokkunと申します。

CS+でRX62をターゲットに開発を行っていますが、

__VA_ARGS__を使うとエラーになってしまいます。

 

CS+           : V6.00.00

コンパイラパッケージ : CC-RX V2.07.00

エラーメッセージ

    *** :E0520020:Identifier "__VA_ARGS__" is undefined ***

 

CC-RXのマニュアルのエラー一覧には

E0520969 : The identifier __VA_ARGS__ can only appear in the replacement lists of variadic macros.

とあるので使用できると思ったのですが、未定義なのでしょうか?

よろしくお願いいたします。

  • わわいです
    ツールチェインのincludeフォルダでgrepかけてみても VA_ARGS は見つからないので、定義されてないようですね

    追記:もしやと思ってstdarg.hを見ると、va_start(AP,LASTARG)、va_arg(AP,TYPE)、va_end(ap) のマクロが定義されていますねー
    必要な人はこれを使ってよろしくやってくださいと言うことなんでしょうねー  

  • ありがとうございます!
    別環境からの移植なのでそのまま使えればと思ったのですが、無いものは仕方がないですね。
    残念ですが実装しなおします。
  • mokkunさん、こんにちは。NoMaYと申します。

    本件は少し引っ掛かっていたのですが、本日ウェブで調べ物をしていて、たまたまウィキペディアの可変長引数の項を読むことがあり、__VAR_ARGS__というのはヘッダファイル中のマクロ定義ではないような気がしました。

    可変長引数 - ウィキペディア
    ja.wikipedia.org/wiki/可変長引数

    C言語のプリプロセッサのマクロ定義において、可変長引数マクロ(英語: Variadic macro)には、以前はトリック的な方法[1]が使われていたが、C99で本物の可変長引数マクロが標準化された。__VA_ARGS__という識別子を使用する。


    実際、CC-RXのコンパイルオプションでC99を選択してビルドするとビルド出来ました。(当方特有の事情でCC-RX V2.03で確認しましたが、たぶん本件はCC-RX V2.07でも同じだろうと考えています。)

    /* Adapted from https://ja.wikipedia.org/wiki/可変長引数 */
    #include <stdarg.h>     // for va_start(), va_arg(), va_end()
    double average(int count, ...);
    double average(int count, ...)
    {
        va_list ap;
        int j;
        double sum = 0;

        va_start(ap, count); /* Requires the last fixed parameter (to get the address) */
        for (j = 0; j < count; j++) {
            sum += va_arg(ap, double); /* Increments ap to the next argument. */
        }
        va_end(ap);

        return sum / count;
    }

    /* Test for https://japan.renesasrulz.com/cafe_rene/f/forum5/4669/rx62-__va_args_ */
    #define MYAVERAGE(...) average(__VA_ARGS__)

    volatile double result = 0; /* for Debug */

    void main(void)
    {
        result = average(3, 1.0, 2.0, 3.0);
        result = MYAVERAGE(4, 1.0, 2.0, 3.0, 4.0);
        for (;;) {}
    }

    以下、CS+の画面コピーです。




    [追記]

    すみません、少し脱線してしまって申し訳ないのですが、C99になると__func__というものも使えるのですね。Goole検索して見付かった個人ブログに書かれていた記述を試してみました。(他の人でも試せるよう、以下のzipファイルにRXシミュレータでデバッグコンソールに出力させるようにしたプロジェクトファイル一式を固めてあります。)

    CCRX__VA_ARGS__20171105.zip 修正 2017/11/06 08:07
    CCRX__VA_ARGS__20171106.zip
    修正内容:
    ・プロジェクト作成時にCCRX__VA_ARGS__としたつもりがCCRX__VAR_ARGS__だったのを修正
    ・2つ目のDEBUG_PRINT()でコピペミスによりaverageとなっていたのをMYAVERAGEに修正
    ・3つ目のDEBUG_PRINT()として"end\n"を出力するものを追加(個人ブログを書かれた人の主目的)

    Google検索: __VA_ARGS__ OR __func__
    www.google.co.jp/search?q=__VA_ARGS__+OR+__func__

    [C++] 可変個数引数マクロの作り方 - tshinoの日記
    d.hatena.ne.jp/tshino/20061123/1164307813

    いろいろ考えたけど、現在のプリプロセッサの仕様では、
    ・マクロの引数が空かどうかを判定(して展開内容を変えたり)できない。
    ・可変個数マクロの引数の個数を判定できない。
    という限界がある模様。
    仕方なく、こんな逃げ方を考えた。


    その記述を先ほどのCC-RXのコンパイルオプションでC99を選択してビルドしたソースに追加してみました。

    /* Adapted from http://d.hatena.ne.jp/tshino/20061123/1164307813 */
    #include <stdio.h>      // for printf()
    #define DEBUG_PRINT(...)  DEBUG_PRINT2(__VA_ARGS__, "")
    #define DEBUG_PRINT2(fmt, ...)  printf("%s(): "fmt"%s", __func__, __VA_ARGS__)

    /* Test for https://japan.renesasrulz.com/cafe_rene/f/forum5/4669/rx62-__va_args_ */
    #define MYAVERAGE(...) average(__VA_ARGS__)

    volatile double result = 0; /* for Debug */

    void main(void)
    {
        result = average(3, 1.0, 2.0, 3.0);
        DEBUG_PRINT("average(3, %f, %f, %f) = %f\n", 1.0, 2.0, 3.0, result);
        result = MYAVERAGE(4, 1.0, 2.0, 3.0, 4.0);
        DEBUG_PRINT("MYAVERAGE(4, %f, %f, %f, %f) = %f\n", 1.0, 2.0, 3.0, 4.0, result);
        DEBUG_PRINT("end\n");
        for (;;) {}
    }

    以下、CS+の画面コピーです。

  • 色々情報ありがとうございます!
    書き忘れていましたが、.cppファイル内で__VA_ARGS__を使用したマクロを定義しています。
    .cで書いてみると問題ないようです。
    ちなみにC99です。

    C++では未実装ということでしょうか。。。
    C99とはありますが、C++についてはいまいち言語仕様がはっきりしないですね。
  • mokkunさん、こんにちは。NoMaYです。

    CC-RXは以下の規格に準拠しているようです。(私は、C++仕様の「互換性のある」「基づいて」という表現が微妙だなぁ、かつ、元々の「Visual C/C++ 6.0」の言語仕様が今では不明だなぁ、と思いました。)

    準拠する言語仕様 - CS+オンラインヘルプ > コンパイラ編 > コンパイラ言語仕様 > 基本言語仕様
    tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/latest/CS+.chm/Compiler-CCRX.chm/Output/ccrx04c0106y.html

    (1) C言語仕様 (lang=cオプション選択時)

    ANSI/ISO 9899-1990 American National Standard for Programming Languages -C

    (2) C言語仕様 (lang=c99オプション選択時)

    ISO/IEC 9899:1999 INTERNATIONAL STANDARD Programming Languages - C

    (3) C++仕様 (lang=cppオプション選択時) ← つまりEC++仕様を選択しなかった場合

    Microsoft(R) Visual C/C++ 6.0と互換性のある言語仕様に基づいています。


    それで、私はGoogle検索して知ったのですが、C++に関してはC++11という規格で__VAR_ARGS__は導入されたようですね。(Visual C/C++ 6.0よりもかなり後ですね。) ですので、CC-RXでは未実装なのだと思います。

    Google検索: C++ __VA_ARGS__
    www.google.co.jp/search?q=C%2B%2B+__VA_ARGS__

    可変長マクロ引数の話 - にっき(pseudo)
    d.hatena.ne.jp/DigitalGhost/20111205/1323098099

    ちなみに、デバッグ用printfに関しては__VAR_ARGS__を使う他に以下に書かれている小技もあるようですね。

    [prog] C99じゃないコンパイラで、可変引数付きデバッグ用マクロを定義する例
    d.hatena.ne.jp/Wacky/20060611/1150007606

    [C/C++] C におけるデバッグ出力のジレンマ - satosystemsの日記
    d.hatena.ne.jp/satosystems/20120810/1344573313

    [追記]

    ウィキペディアにMicrosoft Visual C++の項がありました。Visual C++ 6.0は1998年リリースだったようです。(この項の「4 製品バージョンと内部バージョン」の表を参照しました。)

    Microsoft Visual C++ - ウィキペディア
    ja.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B

    あと、cpprefjp - C++日本語リファレンスというサイトに、このようなページもありました。

    コンパイラの実装状況 - cpprefjp
    cpprefjp.github.io/implementation-status.html

    可変引数が空でない場合のトークン置換 (C++20) - cpprefjp
    cpprefjp.github.io/lang/cpp20/va_opt.html

  • mokkunさん、こんにちは。NoMaYです。

    投稿されている時間帯から、個人ユーザさんかも、とは思いましたが、もし企業ユーザさんでCC-RX製品版を購入されていましたら、ルネサス社の会社としての問い合わせ窓口に問い合わせるのが最も確実ではないかと思います。(もしかすると私も何かオプションを見落としてしまっているだけという可能性もありますので。ここで頻繁に回答している私が言うのも身も蓋もないことではありますが、、、何かが出来ることを言うのは実例を示せば良いのですが、出来ないことを言うのはなかなか確信が持てませんね、、、)

    ルネサス社の会社としての問合わせ窓口
    www.renesas.com/ja-jp/support/contact.html#tech_inquiry

    [関連リンク]

    ルネサスの技術質問の件
    japan.renesasrulz.com/cafe_rene/f/002-2095199602/4580/thread/24385#24385

  • 返信遅くてすみません。
    個人ユーザーです。

    c++11準拠か、そうでなければどのバージョンなのか知りたかったのですが、まさかのvisual Cですか。。。
    6.0久しぶりに聞きました。
    最近聞かなくなりましたが、組込向けだと未だにその辺が主流だったりするんでしょうね。
  • mokkunさん、こんにちは。NoMaYです。

    そうでしたか。個人ユーザさんでしたか。私も、Visual C++ 6.0という名前は、久しぶりに聞きました。この言語仕様が組み込み向けで主流かというと、私はそれは違うのではないかな、と思いました。きちんと集計していないのですが、8ビット/16ビットではC++未対応というケースで集計外ということもあるでしょうし、32ビットでは、IAR Systems, Green Hills Software, Wind Riverなどの開発ツールメーカのC++コンパイラ、ARMCC、GCCといったあたりは以下のようなISO/IEC準拠になっていましたので。

    IAR Systems C++14
    Green Hills Software C++11
    Wind River Diab Compiler C++2003
    ARM Compiler C++98/C++11
    gcc-arm-embedded C++11/C++14/C++17
  • なるほど。
    流石にARMは新しいですね。
    ターゲットの違いって事なんでしょうね。