0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C言語の型に設計上の欠陥を見つけた

Posted at

はじめに

落ち着いて次のプログラムを見てほしい。

# include <stdio.h>

# define PRINT_TYPE(e)\
	printf("typeof " #e " is ");\
	printf(_Generic((e),\
		char:		"char\n",\
		char*:		"char*\n",\
		int:		"int\n",\
		int*:		"int*\n",\
		double:		"double\n",\
		double*:	"double*\n",\
		default:	"unknown\n"));

int main() {
	char* a, b; // 注目するのはこの行です。bの型は何だろう?
	PRINT_TYPE(a);
	PRINT_TYPE(b);
}

型判定のために見慣れないマクロPRINT_TYPEがあるが流してほしい。型判定のために使ってみただけだ。

本題だがchar* a, b;の行に注目してほしい。bの型は何だろう?大事なことなので二度言った。

bの型はchar*であるべきだ。

しかし、bの型はcharになってしまう。

typeofaの型を調べたらchar*だった。

int main() {
	char* a;
	typeof(a) c; //typeofで調べたaとcの型はchar*
}

typeofで型を調べたらchar*になることから、昔からaの型はchar*と認識されていた。

typeofキーワードはGNUコンパイラの独自拡張であるが、typeofはいつ導入されたのだろうか?

GCCをダウンロードできるミラーサイトを調べたところ、gcc-1.21にあってgcc-0.9にないことから、typeofがリリース日の1988年5月1日までに導入されていたことがわかった。1988年の時点ですでにbの型はchar*と認識されていた。

C言語は1972年デニス・リッチーがベル研究所で開発した。

JavaScriptやCの成功を考えると、後方互換性は大事なんだなと思いました。多少欠陥があっても言語設計を直さないほうがいい。

まとめ

char* a, b;におけるbの型に疑問を覚えた。気づけたのはJavaScriptからTypeScriptへと学習を進め型の大切さを認識したためかもしれないと思った。

bの型はcharではなくchar*であるべきだ。

型設計に欠陥があると言えるが、直さないほうがいい。後方互換性が大事なので。

0
0
10

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?