こんにちわ。ojojと申します。
ループ内で宣言したローカル変数をウォッチウィンドウからチェックすると値などが'?'と表示され困っております。ループ外で宣言した場合は表示されるので、そうすればよいのですが出来ればスコープを短くしたいです。
対処法をご存じの方いらっしゃいましたらご教授いただけないでしょうか。
環境マイコン:RX23t仕様ソフトウェア:CS+ ver8.06.00コンパイラ:CC-RX V3.03.00エミュレータ:RENESAS E1エミュレータ
状況(ソースを出せないのでイメージです。スミマセン。)
パターン1main{ while(1){ static uint16_t test=0; test = 1; }//test がウォッチウィンドウで表示できない}
パターン2main{ static uint16_t test=0; while(1){ test = 1; }//test がウォッチウィンドウで表示できる。}
以上です
ojojさん、こんにちは。NoMaYです。#以前は3ヶ月前でしたね。これは第一印象としては最適化を掛けたままでデバッグしているのだ思われます。もしそうであれば、最適化無しに設定変更してみて下さい。そうでなければ、その旨リプライして頂けますか?
NoMaY様、リプライありがとうございます。
最適化はかけておりません。
ojojさん、こんにちは。NoMaYです。そうでしたか。こちらでもプログラムを書いて試してみます。
ojojさん、こんにちは。NoMaYです。こちらでプログラムを書いて試してみると、以下の画面コピーの通り、期待したように表示されましたね。(ただ、CC-RXとCS+のバージョンがそちらと少し違っているのは申し訳無いですけれども。CC-RX V3.04 CS+ V8.07)何か別の要因が関係していそうです。(もともとイメージ的なコードとのことですし。) この場合の通常の対処は、なぜ困っているこちらがそんなことをしないといけないのだ、という理不尽感はあるでしょうけれども、ソースを切り貼り&関数名/変数名を変更して、開示可能で再現可能なものを作成して頂くことになってしまうと思います。以下、CS+の画面コピーです。以下、ソースコードです。
#include <stdint.h>#include <machine.h>void func1(void);void func2(void);void func1(void){ /**/while/**/(1){ static uint16_t test=0; test = 1; test = 0; test = 1; nop(); }//test がウォッチウィンドウで表示できない}void func2(void){ static uint16_t test=0; /*while(1)*/{ /* static */ test = 1; test = 0; test = 1; nop(); }//test がウォッチウィンドウで表示できる。}void main(void){ for(;;) { func1(); func2(); }}
NoMaY様
ご回答ありがとうございます。
ソースコードをコピーし、件のプロジェクトにソースコードを上書きしましたところ、私の環境でも正しく変数内容がウォッチウィンドウに表示されました。
NoMaY様のおっしゃるとおり、私が原因と思っていた部分とは別の部分に原因があるようです。再現性のあるコード作れましたらまた投稿します。ありがとうございました。
ojojさん、こんにちは。NoMaYです。可能性の話としては以下のようなことも考えられますよ。・ CS+のデバッグ情報解釈処理のバグ・ CC-RXのデバッグ情報生成処理のバグ・ CS+のウォッチ変数登録処理のバグ・ ソースファイル名/パス名に記号(+-#など)や半角スペースが含まれていてCS+がうまく扱えないバグ・ ソースファイル名/パス名に全角文字が含まれていてCS+がうまく扱えない(パス名だけならバグに分類かも)・ そのソースに個別コンパイルオプションが設定されていて最適化が掛かったままだった[追記] パス名の件は、少なくとも以下のmain.cの話でも引っ掛かる筈なので今回は違うかな、と思い直しました。思うに調査の初期ステップとしては以下のような手順かと思うのです。(頂いた文面からは、そこまで試されたかどうか不明(main.cのようなソースで置き換えられただけかも)、でしたので、、、)・ くだんのウォッチ出来ない現象が発生している関数において関数の中身まるごと以下に置き換えて発生するのかどうか?
while(1){ static uint16_t test = 0; test = 1; test = 0; test = 1; }
NoMaYさん、
手元のRL78環境では、 `static uint16_t test = 0; ` のコードをデバッガで確認したところ、testの変数そのものが、割り当て無しでした。(標準設定 volatile まで付けるとOK) それでもデバッガ上では変数をモニタ対象に設定可能(?) という謎。
追記.マウス操作を間違えて、`,`(カンマ)を変数として登録できました。当然ながら、値は ? でしたが。 (こちらも謎)
KatoNaganoさん、こんにちは。NoMaYです。> それでもデバッガ上では変数をモニタ対象に設定可能(?) という謎。ojojさんの方の案件で無くKatoNaganoさんの方の案件ですね。これは以下の挙動により一般的なことだと思います。(1) 現在ブレーク中のスコープでは見えなくても次に(或いはもっと先で)ブレークした時にスコープに入る変数を事前に登録することがある(2) 例えば、main()の先頭でブレークしている時(DOS/Windows/Linuxなどではデバッガ起動時の初期状態)にデバッグする予定の関数のローカル変数を事前登録する、など(3) 30年前とか40年前とか、コマンドライン操作が主流だったり、マウス操作がまだ洗練されていなかったり、だったころは(2)は普通のことだった(当時はDOS/UNIXなど)(4) そして、(1)の発想はユーザに拒絶反応を示されること無く現在に至っている(A) ただ、今思えば、当時はCPUパワーもメモリ容量も超貧弱だったので、全関数の全ローカル変数をスキャンすることが得策でなかった、という要因もあるかも(B) もし、数GHz/数十コア/数十Gバイトというのももよくある現在に初めてCソースコードデバッガが登場したとしたら、もっと厳しく変数存在確認チェックが行われたかも[追記]カンマは、カンマ式があるから、というのは詭弁強弁ですが、、、文法チェックが無いのはアカン、ですかね、、、
謎、、と書いた意味は、test という変数の実体が無いのに、追跡可能な変数として登録されるという意味です。CPUも(当然)コンパイラも違うので、RXでtestの変数(実体)が生成されるは分かりませんが。
参考までに... (余計なお世話?)
> test という変数の実体が無いのに、追跡可能な変数として登録されるという意味です。ウオッチパネルは計算式でもキャストでも何でも書けなくてはいけないし、例えばサブプロジェクトのオブジェクトをロードすると変数が消えちゃうとかだと面倒くさくなるので入力に関しては中途半端に縛られるより何でもアリの方がユーザとしては有難いと思います。なぜ変数が表示されないのかが表示されれば親切だと思いますが、ブレークする度にエラーだか何だか分からないものが毎回表示されるのもうっとおしいので難しいですね。
KatoNaganoさん、こんにちは。NoMaYです。こんな感じのことかも。(1) 最適化により実体がなくなった変数は以下のように表示して欲しいThe variable is optimized out.(2) 他方、最適化がどうのこうのに関係なく、スコープ内に変数が無ければ以下のように表示して欲しいThe variable is not found in the current scope.(3) あと、変数名として明らかにおかしいとか、式として明らかにおかしとか、なら以下のようにInvalid variable nameInvalid expression(4) メモリ空間外(ROM/RAM/外部メモリマッピング領域外)とか、なら以下のようにThe address is invalid memory areaちなみに、(1)のような表記はe2 studio(rx-elf-gdb)で見掛けた覚えがあります。(CC-RXだったかGNURXだったかは記憶に定かではないですけれども、、、)