2024-07-28

GCCでは文字列リテラルをstrlenへ渡すと定数に展開される

最近のGCCは標準関数を使ったコードがコンパイル時に計算されてしまうことがあって、良くできている。 例えば、GCCで文字列リテラルを strlen へ渡すと、定数に置き換えられる。

入力コード例: リテラル文字を strlen で数えて返す関数。

#include <string.h>

int func()
{
	return strlen("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}
私の手元にある gcc 13.3.1 20240522 (Red Hat 13.3.1-1) を使用してコンパイルする。
$ cc -O1 -S a.c
コンパイル結果: -O1 でコンパイルしたところ、26を返すだけの関数にコンパイルされる。
func:
.LFB0:
	.cfi_startproc
	movl	$26, %eax
	ret
	.cfi_endproc

具体的な使用例としては、マクロ定義したリテラル文字をその長さと一緒に strncmp へ渡すときのような場合があるだろう。

#define PREFIX "com.example."
int check_prefix(const char *text)
{
	if (strncmp(text, PREFIX, strlen(PREFIX)) == 0)
		return 1;
	return 0;
}
このようなコードを書いた時、 strlen が呼び出されるので処理時間が無駄になるなどと考える必要はない。

2024-07-16

Screenの設定により、Screen上のVimの起動時に誤動作

Screenの中でVimを起動するとなぜか変な文字が入力されるという問題が起こっていたのだけれど、ようやく回避方法がわかった。

前提として、 .screenrc に以下のように設定して Ctrl+G で screen のコマンドを入力するようにしていた。 これを他のキーに変えると問題が起こらない。

.vimrc に以下の記述を加えると、問題が起こらなくなった。

if &term=="screen.xterm-256color"
        set t_RB=
endif
このことから、t_RB (request terminal background color) が悪さをしているらしい。 おそらく、リクエストを出すと screen を通り越して端末に伝わり、端末が結果を返すときに、私が割り当てた Ctrl+G のコードが送られ、それを screen が処理してしまうのだろう。

最終的に、以下のように記述することにした。

if &term=="screen.xterm-256color"
        " For .screenrc setting 'escape ^Ww', t_RB caused an issue.
        " Let's disable all request-type termcap settings.
        set t_RB= t_RF= t_RC= t_RI= t_Ri= t_RS= t_RT= t_RV=
endif