C++を始めてみた(あと、Rustが面白そう)

2025-01-06 07:29:44

英語に集中しなきゃって言ったのは間違いないんだけど、
唐突にC++言語始めてみた。
まずは環境構築から。

環境情報

まずは環境情報。
MacBookAir の、2023 M2

$ sw_vers
ProductName:		macOS
ProductVersion:		14.6.1
BuildVersion:		23G93

GCCインストール

Macでは、clangってのもあるけど、下記を参考に学びたかったので、GCCにする。

ゼロから学ぶ C++

こんなサイトもあったので分からないところはみてもいいかも。
一週間で身につくC++言語の基本

$ brew install gcc

で、インストール自体は楽勝なのだが、
g++コマンドが反応しない。
あれ?と思って/opt/homebrew/bin/配下をみると、g++-14とかのバージョン付きはあるけど、g++はない。

何故なのかは分からないけど、今はそういうものなのかな。
とりあえずシンボリックリンクを作っておく。
C言語を書くこともあるかもなので、gccコマンドも。

$ sudo ln -s /opt/homebrew/bin/gcc-14 /opt/homebrew/bin/gcc
$ sudo ln -s /opt/homebrew/bin/g++-14 /opt/homebrew/bin/g++

これでコンソールを再起動すれば、
g++コマンドが叩けるようになった。

$ g++ --version
g++ (Homebrew GCC 14.2.0_1) 14.2.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

で、前述した、

ゼロから学ぶ C++

を6章ぐらいまでを進めていたらメモリ管理のが出てきて、
最近のC++は、もう自身でdelete書かなくても、shared_ptrやunique_ptrを使う風潮ってことが分かってきた。
なるほど、確かにメモリリークは避けたいもんね。
ポインタは便利だけど、実際のソースではもっと楽したい。

で、そんな感じでC++を調べていたら、

Rustのメモリ管理って面白い #Rust - Qiita

という記事を見つけた。
Rustは名前だけは聞いていたけど、全然知らなかったので、
上記のメモリ管理の仕組みがかなり面白いと思った。
GCに頼るわけでもなく、C++のように自前で管理できるのをどうにか標準ライブラリなどを駆使して問題ないようにしているわけでもないというのが。

C++を一通りやったら、次はRustに手を出してみてもいいかもしれない。

単体テストフレームワーク GoogleTestのインストール (2025/01/07追記)

単体テストをやりたくてGoogleTestを追加した。
homebrewでもパッケージはあるんだけど、入れても動かなかったので、手動ビルド。
ただし、cmakeが必要なので、いれておく。

$ brew install cmake

ではインストール

# Gitから取得
$ git clone https://github.com/google/googletest.git -b v1.15.2
$ cd googletest
$ mkdir build
$ cd build
# cmakeにオプションつけているのは、インストールしたgccでコンパイルしてほしかったため。これを指定しないとMacの標準のclangでビルドされてしまうみたい
$ cmake -DCMAKE_C_COMPILER=/opt/homebrew/bin/gcc-14 -DCMAKE_CXX_COMPILER=/opt/homebrew/bin/g++-14 -DCMAKE_OSX_ARCHITECTURES=arm64 ..
$ make
$ sudo make install

最後のsudo make installで、
/usr/local/配下にインストールされるので、
そこへパスを通すようにコンパイル時などで指定しないといけない。
ということでMakefileはこんな感じ。
今回は最初にCPATHとLIBRARY_PATHに追加する方法でいく。g++コマンドを打つときのオプションでもいいかもしれない。
srcディレクトリ配下に全部のソース入れてある。
最初、-lgtest -lgtest_mainをつけ忘れていて、何度やっても
「Undefined symbols for architecture arm64:」などというエラーが出たが、ちゃんとつけたら上手くいった。
単体テストを動かしたい場合は、make testで、main.cppを除外した版の実行ファイルを作って動かせばOK

ifeq ($(shell uname -p), arm) 
    export CPATH := /usr/local/include:$(CPATH)
    export LIBRARY_PATH := /usr/local/lib:$(LIBRARY_PATH)
endif

TARGET		= cppsample
TEST_TARGET	= test
SRCDIR		= ./src
SRCS		= $(shell find $(SRCDIR) -name "*.cpp" -type f | xargs)
OBJS		= $(SRCS:.cpp=.o)
TEST_SRCS	= $(shell find $(SRCDIR) -name "*.cpp" -type f -not -name '*main.cpp' | xargs)
TEST_OBJS	= $(TEST_SRCS:.cpp=.o)
DEPENDS		= $(OBJS:.o=.d)
CXX		= g++
CXXFLAGS	= -std=c++17 -Wall -Wextra -Werror -Wpedantic -MMD -MP -lgtest -lgtest_main

.PHONY: all
all: $(TARGET)

-include $(DEPENDS)


$(TARGET): $(OBJS)
	$(CXX) -o $(TARGET) $(OBJS) $(CXXFLAGS)

$(TEST_TARGET): $(TEST_OBJS)
	$(CXX) -o $(TEST_TARGET) $(TEST_OBJS) $(CXXFLAGS)

.PHONY: clean
clean:
	$(RM) $(OBJS) $(TEST_OBJS) $(DEPENDS)

.PHONY: fclean
fclean: clean
	$(RM) $(TARGET) $(TEST_TARGET)

.PHONY: re
re: fclean all

.PHONY: debug
debug: CXXFLAGS += -g -O0 
debug: re

参考
Homebrewで入れたC++ライブラリはclangでコンパイルしないとダメらしい #homebrew - Qiita
テスト駆動開発を勉強するためM1 Mac miniでGoogle Testの環境を構築してみた #C++ - Qiita
AppleシリコンでもhombrewでインストールしたCライブラリのパスを通す #C++ - Qiita
ついにッ!最強のMakefileが完成したぞッッッ!!! #C++ - Qiita
Google Test でC言語のプログラムをテストする - とにかく書く

LLDBでデバッグ (2025/01/07追記2回目)

デバッガも使いたいと思ったのだが、
なんとGDBはMacのシリコンチップ(M1とかM2とかのやつ)では、使えないということが分かった。
その代わり、LLDBが使える。コマンドに差はあるが、ほとんどGDBと同じ機能が揃っているみたい。
しかも、clang用のせいか、xcode-selectを入れてあれば、何もインストールしなくても使える。

ただし、最初Makefile内で、GoogleTestに対応するために、CXXFLAGSという変数を別の名前に書き換えてしまったら、
コンパイル時に自動的につくはずのコンパイルオプションがついていなくて、
何度デバッグしても、元ソースではなく、アセンブリでデバッグしなくてはいけなくて、おかしいなって数十分悩んでた。
Makefileの理解が浅いせいだな。。。
とりあえずちゃんとCXXFLAGSのままにしたら問題なくデバッグできた。

参考
lldb で使えるコマンド一覧 - yokaze.github.io
デバッガ (GDB, LLDB)の使い方 - 東京大学工学部 精密工学科 プログラミング応用 I・II




Comments

There are currently no comments on this article, be the first to add one below

Add a Comment

Note that I may remove comments for any reason, so try to be civil. If you are looking for a response to your comment, either leave your email address or check back on this page periodically.