RL78CS+ forCCでソフトを作っています。例えば、関数 void xxfunc(uint32_t, uint32_t) があったとします。メインで、 uint16_t aa; uint16_t bb; aa = 1000; bb = 6000; xxfunc(aa, bb);でコンパイルします。引数の型が合わないのでワーニングが出ると思いましたが出ませんでいた。暗黙の型変換だと思います。このような場合でもワーニングを出すことはできますか?
ega258さん、こんにちは。NoMaYです。試しに探してみたのですが、ソースコードが公開されているLintとして、以下の2つがありました。あくまで可能性のひとつですが、(1)そのまま試して警告が出るか?(2)出なければソースを修正する、という方策もあるかもと思うのです。(ちなみにLCLint/SPLintでは警告は出ませんでした。ADLintはRubyをインストールしないといけないようでしたのでちょっと億劫になってしまい試していません。もちろんソースを修正するということが簡単なことでは無いことは承知の上での、それでも可能性のひとつかも知れない、ということのものです。)・LCLint/SPLint (Cソース)sourceforge.net/projects/lclint/files/splint/3.0.1.6/lclint.cs.virginia.edu/guide/・ADLint (Rubyソース)sourceforge.net/projects/adlint/files/adlint/3.2.14/adlint.sourceforge.net/pmwiki/upload.d/Main/users_guide_ja.html[追記]LCLint/SPLintの実行例です。元がPC向けなせいかuint32_tもuint16_tもunsigned intみたいでしたので、ちょっと小細工しています。(LCLint/SPLintのソースというか定義ファイルを変更すれば小細工は不要になると考えています。)CASE1) このパターンは警告されるソース
typedef unsigned long ccrl_uint32_t;typedef unsigned short ccrl_uint16_t;void xxfunc(ccrl_uint16_t, ccrl_uint16_t);int main(void){ ccrl_uint32_t aa; ccrl_uint32_t bb; aa = 1000; bb = 6000; xxfunc(aa, bb); return 0;}
結果
>set LARCH_PATH=../lib>splint main.cSplint 3.0.1.6 --- 11 Feb 2002main.c: (in function main)main.c(13,10): Function xxfunc expects arg 1 to be ccrl_uint16_t gets ccrl_uint32_t: aa Types are incompatible. (Use -type to inhibit warning)main.c(13,14): Function xxfunc expects arg 2 to be ccrl_uint16_t gets ccrl_uint32_t: bbFinished checking --- 2 code warnings
CASE2) このパターンは警告されないソース
typedef unsigned long ccrl_uint32_t;typedef unsigned short ccrl_uint16_t;void xxfunc(ccrl_uint32_t, ccrl_uint32_t);int main(void){ ccrl_uint16_t aa; ccrl_uint16_t bb; aa = 1000; bb = 6000; xxfunc(aa, bb); return 0;}
>set LARCH_PATH=../lib>splint main.cSplint 3.0.1.6 --- 11 Feb 2002Finished checking --- no warnings
IKUZOさん、
> 値によってはFFFFとか4桁になったりするので
C99 以降の仕様であれば printf の第1引数に長さ修飾子 hh を指定することで引数が char であることを明示できます。
#include <stdio.h> int main(void) { char b = 0xff; printf("%02X\n",b); printf("%02hhX\n",b); }
FFFFFFFF FF
Wandboxで実行
ega258さん、こんにちは。NoMaYです。> 型違いの同士の計算(代入)を言いたかったため、そう書いたのです。> 「uint8_tとint16_tの掛算や割算などの演算を無事に行う書き方はありますか?」> とお尋ねすれば良かったと反省しております。これはまた別の方向へ迷走するだけのような気がします。思うに、ega258さんは変数の値の実行時チェックを行わない言語と相性が悪い(好みに合わない)、と表現されるような方向へ向かって行ってしまうかな、という気がします。(さらには、そういうチェックを行う言語はマイコン向けの言語としては一般的では(というか業務案件向けでは)無かったりします。)、、、でも、それでは不十分なのかな、、、そういう言語に乗り換えても、今度は、実行時エラーが起きないようにする書き方はありますか?という問いに置き換わりそうですね、、、う~ん、なんでしょうか、ポイントは2つあるのかな、という気がしてきました、、、(1) C言語に限らず殆どの言語では、所詮、完璧な対策は無理、である。(2) 型違いの同士の計算(代入)には、安全なものと安全では無いものの2種類、がある。あるいは、このスレッドとしても、私が以前に別スレッドでega258さんへ返信したように、以下の返信とするのが良いのかも知れない、という気もしてきました、、、CS+やe2studioのコンパイル設定japan.renesasrulz.com/cafe_rene/f/forum21/6333/cs-e2studio/35087#35087「●CC-RL自分が認識している範囲ですと -refs_without_declaration がこのカテゴリのものですね。(正確には、ワーニングにするかどうかでは無く、エラーにするかどうかの設定になりますけれども。) ヘルプでは、コンパイラ編→コマンドリファレンス→オプション→コンパイルオプション→機能拡張のグループ分けの下にあります。「宣言がない関数を呼び出す場合,または古いスタイル(K&R)の宣言が書かれた関数呼び出しをエラーとします。[指定形式]-refs_without_declaration - 省略時解釈 宣言がない関数を呼び出す場合,または古いスタイル(K&R)の宣言が書かれた関数を呼び出す場合にメッセージを出力しません。[詳細説明]- 宣言がない関数を呼び出す場合,または古いスタイル(K&R)の宣言が書かれた関数を呼び出す場合にエラーとします。」●CC-RX自分が認識している範囲では以前に以下のスレッドに書いたような状況ですが、その後、Amazon FreeRTOSのCC-RXへの移植を行った時に多少更に理解が深まっていて、特に続報とか投稿していませんが、自分が投稿するサンプルプログラムは少し細かい設定をしています。(カットアンドトライで、緩やか過ぎず、厳し過ぎず、の落としどころを探したものです。)CC-RXでWarning Levelを上げるOptionはインフォメーションメッセージ出力オプションだと知ったので試してみましたjapan.renesasrulz.com/cafe_rene/f/forum21/4434/cc-rx-warning-level-option●CC-RH最新版のV2.02.00のヘルプを調べてみたのですが、このカテゴリのオプションは無いようでした。たぶん、緩やか過ぎず、厳し過ぎず、の落としどころに設定されているのだろうなぁ、と思います。(あるいは、実務上は、MISRA-Cルールチェックを行うのがデフォルトなので、そちらで細かい設定をするから、といったことだったりするのかも知れません。)」
>「uint8_tとint16_tの掛算や割算などの演算を無事に行う書き方はありますか?」
C言語ではint同士の演算でもオーバーフローや 0除算をさせないことはプログラマの責任になります。assert() をまめに用いる等でそれを検出することも不可能ではありませんが自動でそれを行う方法は通常用意されていません。
C Swift Rust