質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

組み込み開発

組み込み開発とは、スマートフォンや家電、自動車などに組み込まれているコンピューターシステムの開発のことです。特定の用途に特化しており、限られた機能のための開発を指します。組み込み開発で作られた機器を組み込み機器と呼び、近年ではPCのオペレーションシステム(OS)にも採用されています。

Q&A

8回答

6697閲覧

組み込み開発でグローバル変数をどこまで許容できるか

MrSoumen

総合スコア8

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

組み込み開発

組み込み開発とは、スマートフォンや家電、自動車などに組み込まれているコンピューターシステムの開発のことです。特定の用途に特化しており、限られた機能のための開発を指します。組み込み開発で作られた機器を組み込み機器と呼び、近年ではPCのオペレーションシステム(OS)にも採用されています。

4グッド

3クリップ

投稿2021/09/21 15:44

前置き

(初めての質問なので過不足があったらご容赦ください)
C言語で組み込み開発(モータ系)を行っています
組み込み業界に移ってからまだ1ヶ月ほどで業界の標準がまだ分かっていない状況です

プロジェクトのコードを見ると関数間の値の受け渡しを殆どすべてグローバル変数に格納しています(引数、戻り値がvoid)
また、一つの関数内でしか使用しない変数も前回値を保存するためにグローバルです
上長に「グローバル変数を引数や戻り値、関数内staticを使うようにしないのか」と聞いたところ回答に対して一理あるな、と思う反面、腑に落ちない点も残ったため他の方(他社さん)はどのように扱っているのかをお聞きしたく質問させていただきました

一応私は「グローバル変数絶対に許さないマン」ではなく
・異なる割り込み間で値をやり取りする為にグローバル変数が必要となる
・変数のメモリへの配置を予め決められるため(?)必要なこともある
という認識です

グローバル変数に対する上長の弁

(実機テストや客先など)現地で不具合が発生したとき、直ぐに値を確認できる。ローカル変数だと確認できない
ROMには余裕があるからグローバルでいい

デバッグ用にソフトを作成、書き換えをしなくてもよい、という点に関しては一理あるなと思うのですが、これば組み込み業界で一般的な考えなのでしょうか?

個人的には
不具合が出る前提で話をする点に違和感を覚えました
また、グローバルであることで、意図しない所で書き換えられる、単体テストができなくなる、リファクタリングができなくなる、などデメリットの方が圧倒的に大きい気がします(まぁ、単体テストもリファクタリングもしていないらしいのである意味問題ではないのかもしれませんが……)

ozwk, fana, episteme, Nyanmage.neko👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答8

0

何の理由もなくやたらめったらにグローバル変数にしている! みたいな残念な形の話なのではなくて
ちゃんと然るべき理由があってのことでしょうから,(「一般的」かどうかは私にはわかりませんが)一つの形であろうと思います.

プロジェクトのコードを見ると関数間の値の受け渡しを殆どすべてグローバル変数に…

とのことから,
「殆ど」,すなわち 全てではない のでしょうし.
そのような形にしておくべきもの と しなくてよいもの の切り分けはちゃんと存在するのだと想像します.


実際にそのようなコードを自身では書いたことはありませんが,
そういう雰囲気のファームが入ってるブツを相手にしたことはあります.

外部から特定の手段を用いて値をReadできるだけでなく,Writeして挙動をみたりもできるわけで,ブツの性質次第では必要(というか大変に重要)なことに思えましたよ.

そのような形態とすることの理由(意義)をあなたが把握/納得できるまで,しっかりと尋ねてみると良いのではないでしょうか.

投稿2021/09/22 01:28

fana

総合スコア11996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/09/22 01:43

> グローバルであることで、意図しない所で書き換えられる、単体テストができなくなる、リファクタリングができなくなる 「単体テスト」とかいう形で切り分けられる性質のモジュールが存在するのであれば,そいつは実機でない場所でいくらでも十分に検証すればよい. 意図しない所で書き換えられる,リファクタリングがどうの… という話に関しては, **プログラマがこの設計に関してしっかりと理解しているならば**,そもそも意図せず書き換えないのでOK(!). リファクタリング…の機会が本当にあるのかどうかはわかりませんが モジュールなり関数なりの処理単位の IN/OUT がどの変数なのか? という規定さえあれば(←当然あるハズ)その単位で可能でしょう. 要は「グローバル変数だとこういうミスがどうの」みたいなコーディングに関する人為的ミスなんてのはそれこそ客先に行くよりも前に潰されている(ハズである)のであって, この話で想定されている「デバッグ」とはもっと厄介な話のことであろう,と思う.
fana

2021/09/22 02:08 編集

グローバル変数を 「許す/許与する」 という視点自体が違う,というか,話に対してずれてる可能性があるんじゃないかな,という. 必要なのは,達成すべき事柄を達成するための手段としてのプログラムなのであり, 達成すべき事柄に 【そのような「デバッグ」ができること】 が含まれているのかもしれない. もしもそうであれば,「この変数はさー,ふつーはローカルにするっしょ」的な話には何の価値も無いわけだ. なぜならば,そのようにしてしまったら 目的が達成できない のだから. --- ある目的を達成するための実装方法としてグローバル変数が最も適しているならば,グローバル変数を使うのが妥当. そうでないならば → 「そこはどうなの?」という話を入れ込む余地がある. グローバル変数はどうなの? とか言うよりも前に,まずは「そうでないならば」なのかどうかをもっとちゃんと確かめると良いだろう.
pepperleaf

2021/09/25 00:38

> 何の理由もなくやたらめったらにグローバル変数にしている!  自分の周りだけかも知れませんが、結構、出会ってます。大抵は、ここでプログラム覚えたって人が多いように感じますが。
fana

2021/09/25 00:57

最初にCとかから入ると,いきなり出てくる「スコープ」とか「寿命」みたいな話が「なんかよくわからん面倒なルールだぜF●CK!」みたく思えるのかもしれませんね. 先にN88-BASICとかに触れてると「スコープ……寿命……なんだこのルールは… 神か!?」ってなるので,超おすすめ.
fana

2021/09/25 00:59

「引数……戻り値……なん(略 」 も同時に経験できます.
dodox86

2021/09/25 01:29

> 先にN88-BASICとかに触れてると「スコープ……寿命……なんだこのルールは… 神か!?」ってなるので,超おすすめ. しかしそれも、そのこと自体に苦労されていないとスコープのメリットを実感できませんね。それこそプログラム規模もありますが苦労と感じず、「そんなもんだ」でやり過ごせる方も大勢いるように思います。
guest

0

それはそのプロジェクトの規約、とかそのひとの考え方次第、のはなしかと。
あなたがそこらへんを決定できる立場にあるなら、あなたが決めていけばいいかと思います。
まあたしかに、グローバルにしとけばデバッガでいつでもその値を確認できるってので一理はありますが、それを理由に何でもかんでもグローバルにするってのは話が違うかと思います(これも私の考え方、ですが)

まあ、組み込み用途ではスタックサイズはあまり大きくしないので、サイズの大きなローカル変数は使えないという事情はありますが。

投稿2021/09/21 22:08

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

コードを書く際に保守性、安全性などを考慮する必要があります。
長期間にわたって複数人で開発する際に全部グローバル変数だと大量のファイル、コードを逐一確認する必要が出てきてやってられません。

非常に簡易なプログラムを自分一人で作成する場合は全てグローバル変数でも問題は生じないと思います。ただ多少経験を積めば意識しなくとも自然とスコープを意識してローカル変数を使うようになるとは思いますが。

なんか低評価ついちゃったんで追記
グローバル変数だらけだとデメリットの方が多そうとのことですが、一般的にはその通りです。一般的というのはコード量や開発体制が企業案件向けのようなものであればという意味です。少なくとも業界標準でこう書くべきというのはなく、書籍のリーダブルコードにある内容を一般論として念頭に置き、プロジェクト毎にリソースを考慮してルールを決めるものだと思います。
不具合が出る前提で話すのは違和感ありませんが、不具合が出る前提なら尚更グローバル変数は減らす方がメリットがあります。
グローバル変数だらけの方がデバッグがしやすいというのは聞いたことありませんね、仮にそうなら組み込みに関わらずみんなグローバル変数をもっと推奨するのではないでしょうか。
組み込みならではの話でいうと容量を考慮する必要がありますが、近年は容量より保守性や可読性が重視されているように感じます、その方がトータルコストが安くなるからです。ということで、追記前の内容と同じ結論になってしまいますが、小規模な個人開発案件でもない限りは極力グローバル変数を減らす方向とするのが良いはずです。業界標準はないのであくまで個人の感想です。

投稿2021/09/23 04:26

編集2021/09/23 05:19
YOshim

総合スコア1085

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2021/09/23 04:31

それを踏まえた上での質問でしょう。 何を意図した回答なのかわかりません。
fana

2021/09/23 04:58

低評価理由: 話がかみ合っていない(質問者のしている話に対する応答になっていない)と見えるため.
Zuishin

2021/09/23 05:30

追記を読みましたが、「組み込み」という言葉を知らないということなんですかね? 低評価しておきます。
fana

2021/09/23 05:43

回答に追記が成されたことに対するリアクション: 質問者のしている話に関しての話が書かれている形態になった(:少なくとも前記した低評価理由が解消された)かと見えるので,低評価を取り下げる.
thkana

2021/09/23 06:31

低評価はしてませんが。 > コード量や開発体制が企業案件向けのようなものであれば 多分、そうじゃない話です。具体的なところは不明ですが、モーターをぶん回すのであればROM容量で64KB以内、RAM16KB以内(もっと少ない気もする)を1人からチームでも派生機種含めて5人以内とかでの開発を想像します。あなたが「小規模な個人開発案件」と片付けてしまっている規模の可能性が高いです。 > グローバル変数だらけの方がデバッグがしやすいというのは聞いたことありません 判断基準は「聞いたことがあるかどうか」なのですか? 例を考えるなら...大電力の制御であれば下手にブレークを掛けるとターゲットシステムが破壊される場合も有り得ます。そういうときにローカル(auto)変数では観察できないが、静的寿命を持たせておけば安全なところでブレークをかけて痕跡ぐらいは確認できる、という事態は容易に思いつきます。 もちろん、「画面」なんてものはなくてprintfデバッグもできないのが普通ですよ、組み込みでは。
fana

2021/09/23 08:16 編集

> (実機テストや客先など)現地で不具合が発生したとき への備え,っていう話ですからね.そもそも. 以下は私の勝手な想像ですが… 実際に何の用途に使われる何を作ってるのかは不明ですが, ある日突然客先から報告された不具合現象の要因を突き止めるための作業としてどのような事柄は可能で,どのような事柄は不可能なのか? …っていう背景事情があっての施策だと思われる. すなわち, コードの保守性だとか可読性だとかいう話とは根本的に異なる事情からくるものなのであって,どの程度の規模かなんてのも無関係. 問題が発生している現場は実際に使っている客先であるわけで,そこに出向いていってその装置か何かがある場所に立ち入って実際に問題現象を起こしながらコードをデバッグ実行できるような世界ではないのかもしれず,そのような世界では「あそこの自動変数の値を見ないとわかんねー」とかいう状況は詰んでいるわけで.
pepperleaf

2021/09/25 08:19

> グローバル変数だらけの方がデバッグがしやすいというのは聞いたことありませんね、 thkanaさんも書かれていますが、ありますね。 質問者さんのケース((モータ系))も途中で止めると、モータが壊れるケース(制御の方法にもよるが)。 こんな時は、線出して、オシロでみる事もあるが、自分だとまず、グローバル変数に途中経過を出す。 デバッガで見る時、ローカル変数だと正しく表示されない事も多々。(デバッガの問題だけど)そうするとやっぱりグローバルにしたくなる。ローカル変数と違って、グローバル変数の寿命は長いので。
guest

0

個々の要素の重みはそれぞれのケースで変わってくるでしょうから、個々の判断と言ってしまえばそうなってしまうでしょうね。
ぼちぼちとかいつまんで。

デバッグ用にソフトを作成、書き換えをしなくてもよい、という点に関しては一理あるなと思う

一理はありますけれど、そういうコンセプトを貫いたプログラムはあまり見たことがありません。少数派ではあるのでしょうね。

不具合が出る前提で話をする点に違和感を覚えました

これだけは「完璧なプログラムなんてあり得ない」という考えで挑まないと仕方ないとは思いますけれど。

意図しない所で書き換えられる

これは「管理しきれるか」という問題なので、大抵に於いて規模が小さめの組み込みプログラムでは重み付けが下がるように思います。

リファクタリングは...あまりやらない気がします。
いまでこそFlashメモリを積んだマイコンが普通になりましたけど、ちょっと前まではマイコンなんてマスクやOneTimePromが普通で一度書いたら固定されてしまうので、そもそもリファクタリングの機会がない、というところがありました。また、リファクタリングの際にはテストで以前との等価性を保証することになるのでしょうけれど、ハード部分の抽象化が難しく完全なテストがしにくいというところもあるのではないでしょうか。

メモリ消費については、グローバルのほうがRAM消費が増える可能性もある(ローカル変数はテンポラリなので平均化できればピークの使用量は減るかもしれない)かと思いますが、最大使用量の管理がやりやすいというのは厳しい環境では有用なことでもあるでしょう。

ROMには余裕があるからグローバルでいい

グローバル変数の方がROM容量を喰う、という有意な差があるかしら?

関数内staticを使うようにしないのか

これは組織の文化かなぁ? 変数のスコープ以外はグローバルと変わらないですからね。

投稿2021/09/21 23:19

thkana

総合スコア7703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/09/23 08:41

> 「完璧なプログラムなんてあり得ない」 動作不具合の要因がプログラムの実装バグだけとも限らない気もしますね. 何らかの外部入力が想定外に遅延した場合だとか,ある実施環境では信号が鈍ってごく稀に閾値を下回るだとか… (「そういう状態でも常に正当に動作するのが完璧なプログラムだ!」って言うなら,悪いのはプログラムということになるけど…)
thkana

2021/09/23 12:06

ハードに間違いがあっていまさら直せないからソフトで頑張ってリカバリしてね、なんていうのもあるあるです。
guest

0

組み込み系でもソフト系と電気系のプログラマに分かれます。
ソフト系は基本的にグローバル変数を使うメリットよりデメリットが多いですが、電気系の人は良く使います。
これは昔からトラ技(トランジスタ技術)のソースコードがグローバル変数を多用していた経緯があると思ってます。
恐らくですが参照渡しでさえ関数に引数を渡すとメモリの使用量が増えるのを嫌っての事じゃないかと。

投稿2021/09/24 08:48

kalen

総合スコア4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2021/09/24 21:48

> トラ技(トランジスタ技術)のソースコードがグローバル変数を多用していた経緯 いくらなんでもそりゃないだろう、と「思います」。
pepperleaf

2021/09/25 00:45

> 昔からトラ技(トランジスタ技術)のソースコードが 個人的見解ですが、トラ技とか、IF誌とかは、動く(使える)事が主眼で、その他は結構、怪しく思ってます。(だから、コードの品質もそれなり、、、) 最近、読んでないので、今は違うかも知れませんが、、。 まあ、それはそれで役に立つので重宝したのも確か。
kalen

2021/09/27 10:23

thkanaさん 同感ですよっと言うか同じ感想を持ったことがあります。 2000年代に電気系の駆け出しの人が書いたプログラムをチェックさせられたことがあって、指摘の一つにグローバル変数使わなくて良いんじゃ?と指摘したら、トラ技がそうなってるからって言われた経験があります。 ソースコードのボリュームが少ない単独の機能なら、ソースコードの文字数を減らせるのも確かなのでこだわる程じゃないと思ってスルーしましたが・・・。 昔は文字数を減らす努力をしてた時代もあるのでその経緯があるのかもしれませんね。(サーバー→サーバと表記したり)
guest

0

組込み開発との事ですが、どの程度の規模でしょうか?
多分、規模によって回答が異なるでしょう。組み込み用OS(Linux, Windows, etc.)を使って、メモリもいっぱいあるところとか、、。

C言語で組み込み開発(モータ系)を行っています

との事なので、小規模でしょうか? Flash 16KB, Ram 16KBとか...? もっと小さい?
このような前提だと、、(今、そんなところでやってる) グローバル変数、使いますね。

現地で不具合が発生したとき、直ぐに値を確認できる。

これはやり方次第。もっとも今、使ってるデバッガ、まともにローカル変数表示してくれない。最適化の影響もあるみたいですが、アセンブラ追って、レジスタ参照。これがヤダとグローバルにするでしょう。

ROMには余裕があるからグローバルでいい

RAMの間違い? でしょうか。それもありですね。迂闊にスタックオーバーするより、RAMにマッピング。

不具合が出る前提で話をする

これは組み込みでなくても当然だと思うのですが、別のところだと非常にいやな顔された。
組込みの場合、ハードウェアが歴史が長く、不具合無しが理想でも現実にあり得ない事が分かっている人が多いのではないかと思います。

グローバルであることで、意図しない所で書き換えられる

ある程度までは静的に検査可能では?

なお、

他の方(他社さん)はどのように扱っているのかをお聞きしたく

余り具体的には書けないです。機密とまではいかなくても、うっかりもあるので。(逆に簡単に書く人は...)

以下、個人的感覚ですが、
組み込み系は、ハードがまずあって、おまけ的にソフト開発される事が多いようです。(特に小規模)
そのため、ハード屋さんが片手間、、も多い感じ。ソフト専門の人からすると、なんでこんなの、、というコードが多いと思います。また、組み込み系特有の処理(特定の順番でポートアクセスとか)からの制約とかで、不適切と思われるコードになる事もあるようです。(不必要に多量の volatile, static 等)
あと、今使ってるツール、初期化部分を自動生成してくれるのですが、個人的には ?のコードです。これを参考にしたら、グローバル使いまくり。もっともTimer/IOマップとかをGUIで生成できるので止められない、、と言ったところ。

投稿2021/09/23 08:41

pepperleaf

総合スコア6385

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pepperleaf

2021/09/23 08:55

おっと忘れてた。古い人だと過去のトラウマがあるとか。 かなり昔の話ですが、特定のパターンで、引数がちゃんと渡らない、てコンパイラバグもあった。こんなのに出会うと、しばらくダメ。 あと、スタック上の(ローカル)配列は、バグの原因となる事がある。(バグなので、当然、本人責任だが) そんなので避ける人もいるのでは?
guest

0

業務としてソフトウェアを開発する場合、業務の必要性を無視して教条主義的に原則論に凝り固まるのはやめましょう。

ご質問の文を読む限り、まだ明確な質問ができない方のように思えます。
組み込み開発(モータ系)といえば開発内容が伝わるものではありません。
製品のライフサイクル全体で100万セット出荷されるモーターと、カタログ販売をして年産100個のモーターと、注文生産で年あたり十数台出荷するモーターで話は全く違ってきます。
ソースコードが1Mなのか10Kなのか数百なのかでも違ってきます。

他の方も書いていらっしゃいますが、「不具合が出る前提で話をする点に違和感を覚えました」というのも勉強不足の感が否めません。あと一年組込みソフトを開発して同じように考えているのなら、そうそうにソフト開発以外の仕事に転職することをお勧めします。
仕事としてのソフトは、設計20%、主たるロジック10%、異常時処理20%、テスト20%、出荷後不具合対応30%ぐらいの工数配分のものも多数あります。特に、年間十数台のシステムでは不具合対応に必要な工数の比率は高くなります。

仕事の内容が明確に書かれていないので,確実なことはいえませんが、年あたり十数台の出荷でソースが1K以下なら、私でもあなたの上長と同じ判断を下すかもしれません。

投稿2021/09/22 03:51

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

グローバルを使用した方が良いかどうかの回答ではありません。

個人的には不具合が出る前提で話をする点に違和感を覚えました

あなたが、違和感を感じるのは、「(実機テストや客先など)現地で不具合が発生したとき」のインパクトを上長と同じように受け止められている訳ではないので、仕方ないでしょう。

不具合は発生するものとして考えるべきです。

グローバルであることで、意図しない所で書き換えられる、単体テストができなくなる、リファクタリングができなくなる、などデメリットの方が圧倒的に大きい気がします

発生率は押さえるようにするべきなのですが、その対応コストが見合うかどうかの判断も当然あります。
その疑問を上長にぶつける事で、ここでの曖昧な回答より現実に即した回答が得られると思います。

投稿2021/09/22 00:26

編集2021/09/22 07:36
sazi

総合スコア25327

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問