2019年1月28日月曜日

.bssセクションのグローバル変数の初期化について

こんにちは、ふじかーです。

先日現場で グローバル変数の初期化 が話題に上がりました。

「このグローバル変数で判定してますね。値、何が入ってるんだろ」
「定義時には特に初期値入れてないですね」
「あら、判定までずっと値入れてないですね。じゃ値は0ですか」
「なんか不定値になることありませんでしたっけ?」
「必ず0初期化されるんじゃなかったですかね?」

昔調べた気がするけど、正確にはどうだったか・・
と曖昧になっていたので、少し確認しなおしました。

セクション


プログラムはメモリに配置されて実行されるわけですが、メモリ上には
プログラム内の「機械語」や「変数」「定数」など、各種用途ごとに分かれて配置されています。

その単位のことをセクションといいますが
今回のグローバル変数などは『.bss セクション』という領域に格納されます。

.bssセクションに格納される変数の種類は

・初期値 なし の グローバル変数
・初期値が 0 の グローバル変数
・初期値 なし の 静的(=static)なローカル変数
・初期値が 0 の 静的(=static)なローカル変数

となっています。

この.bss領域は「全て0初期化されているべし」とC言語の規約で規定されているため
プログラム実行前に、領域を確保して丸ごと0初期化されるようです。

wikipedia
通常、bssセクションに割り当てられたメモリは
プログラムローダーがプログラムをロードするときに初期化する。
main() が実行されるより前に
Cランタイムシステムがbssセクションにマップされたメモリ領域をゼロで初期化する。

ちなみに、初期値あり(0以外) のグローバル変数や静的ローカル変数は?というと
『.dataセクション』 という領域に格納されます。
プログラム実行前に、領域を確保して値を格納していきます。

また、「const」がつけられる定数が格納されるのは
『.rodataセクション』 という領域です。

さらに関数などプログラムの機械語そのものは
『.textセクション』 という領域です。


メジャーなのはそのあたりですが、
ビルド後の実行ファイルの各セクションがどのように配置されるか、
下記のコマンドで確認することができます。

>objdump -h a.exe



落とし穴


初めの話に戻り、.bssは 言語の仕様として0初期化される と決まっているので

「じゃあグローバル変数は自動的に『起動時0初期化処理』されてるものとして
 使うときも特に初期化せずに使えば良いね」

と考えられるかというと、そうでも無いようです。


場合によって、例えば組み込み機器などで

「電源投入からプログラム起動までの時間を極力短くしたい。
 メモリの初期化時間ですら、可能なかぎり限界まで削りたい」

というシーンでは、

やろうと思えばこの『起動時0初期化処理』を省くことができるようで、
そうすると実行時のグローバル変数には「不定値」が入っていたりするとの事。

やはり変数を使う前には、明示的に値を入れて初期化してから使う方がよさそうです。
見つけにくいバグや、不要な不安やトラブルを避けられますもんね。
今後実装する時やレビューする際は、気を付けたいと思います。

※関連記事:メモリのセクション内の配置を確認してみた

2019年1月19日土曜日

git コマンド チートシート。これだけは覚えておきたい!



こんにちは。よっしーです。

複数人のプロジェクトに参加すると、

もれなくついてくるのが、バージョン管理システムです。


少し前までは svn をよく使っていたのですが、

時代の流れもあり、最近では git を使うようになりました。


現在は、開発環境がLinuxなので、GUIツールは使わず、

端末上で git コマンドを直接叩いて処理しています。


せっかくなので、これだけ覚えていれば一通りの作業は出来ますよ。

というものを自分用の備忘録として以下にまとめます。




1.git リポジトリを取得

git clone https://リポジトリアドレス

この場合、デフォルトで master ブランチが取得されることになるので、
master 以外のブランチを直接取得する場合は、以下のブランチ指定で clone する。

git clone -b ブランチ名 https://リポジトリアドレス



2.git の設定

ユーザ名とEメールの設定

git config --global user.name ユーザ名
git config --global user.email Eメールアドレス

(この設定をしないと git へ commit 出来ない。)

git commit する時、パーミッション変更を無視する設定

git config core.filemode false



3.commit 関連

変更内容をaddする

git add コミットしたいファイル

全ての変更内容を add する場合は以下。

git add -A

変更ファイルなどの一覧を確認

git status

変更内容をコミット

git commit -m コミットログ

リポジトリへ反映

git push origin ブランチ名



4.差分確認

add する前に変更点を見る

git diff

add した後に変更点を見る

git diff --cached

commit した後に変更点を見る

git diff HEAD^



5.コミットログ確認

ログを確認

git log

ログを差分付きで確認

git log -p



6.ブランチ操作

変更の取り消し(追加されたファイルは残る)

git checkout .

ブランチ切り替え

git checkout -b ブランチ名 origin/ブランチ名



7.コミットログ

git commit する際のコミットログ(変更履歴)ですが、

業界的には「明確で簡潔に英語で!」というのがスタンダードになりつつあります。

英語が苦手な私は、これを考えるのに、なかなか時間がかかったりします。


そういったコミットログを考えるのに困っている人のため、

コミットログの例文をまとめているサイトもあります。

かなり、ここには助けられていますので、同じような人は参考にしてみてください。




ではまた~。

2019年1月12日土曜日

Visual Studio Code で C++ と Python をデバッグする


こんにちは、ふじかーです。

明けましておめでとうございます。本年もよろしくお願いします。

さて、こないだ下記の記事で VS Code でC言語デバッグできるようにしたんですが
Visual Studio Code でC言語をステップ実行

現場で C++ を扱う可能性が出てきたので、
そちらも VS Code で動かせるようにしたいと思います。

あと、ついでに Python も動かせるようにしたいと思います。

C++_デバッグ環境作成の流れ


    基本的に前回の C言語環境 作成時と同じ流れです。
    ファイル名や設定が少し異なるくらい。
    → ここまでは C言語環境 作成時と全く同じ手順ですので
      前回の記事にリンクしています。実施済みの場合とばしてください。



    C++_作業場所、test.cppの準備


    C言語の時と同じく、適当にHelloWorldソースを用意します。

    #include <iostream>
    
    int main() {
        std::cout << "Hello, world!" << std::endl;
        return 0;
    }
    

    これを作業フォルダに保存しておきます。ここでは D:\test\cpp\test.cpp としました。

    またこの作業フォルダを、VS Code のメニューから開いておきましょう。
    ・メニュー → フォルダーを開く → D:\test\cpp



    C++_デバッグの為の設定

    • ビルドタスクの設定(tasks.json)
    修正したソースコードをビルドするための設定を行います。
    ほぼC言語の時と同じで、コマンド行が下記のように異なるだけなので
        C言語・・・ "gcc -g -O0 -o a.exe test.c"
        C++   ・・・ "g++ -g -O0 -o a.exe test.cpp"

    C言語の時の tasks.json があるならファイルコピペして
    コマンド行だけ編集してもOKです。

     ・フォルダーを開いている状態で Ctrl+Shift+B
     ・「実行するビルドタスクがありません。ビルドタスクを構成する」というメッセージが出るのでクリック
     ・「テンプレートからtask.jsonを作成する」というメッセージが出るのでクリック
     ・表示された候補の中から「Others 任意の外部コマンドを実行する例」を選択
      → 作業フォルダ内に「.vscode/tasks.json」ファイルが自動生成され、画面に表示される




     ・表示された task.json の
    "command": "echo Hello"
    
      を削除して、下記を挿入
    "command": "g++ -g -O0 -o a.exe test.cpp",
    "problemMatcher": "$tsc", 
    "group": {
        "kind": "build",
        "isDefault": true
    }
    
     ・Ctrl+S で保存しておく


    • デバッグ環境の設定(launch.json)
     デバッグに必要な設定を行います。こちらはC言語の時と完全に同じなので、
    C言語の時の launch.json があるならファイルコピペでもOKです。

     ・画面左のデバッグアイコンを押下
     ・デバッグの開始アイコン(再生マーク)を押下
     ・表示された候補の中から「C++(GDB/LLDB)」を選択
      → 作業フォルダ内に「.vscode/launch.json」ファイルが自動生成され、画面に表示される




     ・表示された launch.json の
    "program": "enter program name, for example ${workspaceFolder}/a.exe",
    "miDebuggerPath": "/path/to/gdb",
    
      を削除して、下記を挿入
    "program": "${workspaceRoot}/a.exe",
    "miDebuggerPath": "c:\\mingw\\bin\\gdb.exe",
    
     ・Ctrl+S で保存しておく



    C++_デバッグ開始!


     ・試したいコードをmain関数に記載し、リビルドは Ctrl+Shift+B
     ・ブレークポイントをセットしてF5でデバッグ開始、F10でステップ実行



    Python_デバッグ環境作成の流れ


      お次は Python です。
        →  ここも同じ手順ですので、実施済みの場合とばしてください。



        Python3のインストール


        パソコンにまだPythonを入れていない場合、
        下記サイトに従ってインストールしておきます。








        Python_拡張機能をインストール


        C言語の時と同じく、Python開発用の拡張機能もインストールしておきます。
         ・画面左の 拡張機能(Extensions)ボタン を押して「python」で検索 → インストール → VS Codeを再起動






        Python_作業場所、test.pyの準備


        C言語の時と同じく、適当にHelloWorldソースを用意します。

        a = "Hello World!"
        print(a)
        

        これを作業フォルダに保存しておきます。ここでは D:\test\python\test.py としました。

        またこの作業フォルダを、VS Code のメニューから開いておきましょう。
        ・メニュー → フォルダーを開く → D:\test\python



        Python_デバッグ開始!




         ・ブレークポイントをセットしてF5でデバッグ開始、F10でステップ実行


        Pythonはインタープリタ言語なのでビルドとか必要ありません。お手軽。
        ただこのとき、こんなエラーメッセージが出る事があります。



         これはPythonのLinter(構文チェッカ)が入ってないよ、というエラーのようなので
         インストールしておきましょう。