Edited at

侍エンジニア塾の記事が炎上しているので追撃してみる

この記事話題になってますね。セキュリティホールの宝石箱や!って感じ。

https://qiita.com/hamichamp/items/7b7a7ee091a6856ac900

同じ作者の記事で、問題あるのがまだまだ掘れそうだなぁと思ったので、キャストの記事について突っ込んでみます。

https://www.sejuku.net/blog/25737


数値型の精度

まず数値の精度について、以下の順と紹介されてるけど、明らかに間違いですね。


精度の順序は下記のとおりです。

double型 > float型 > long (int)型 > int型 > short (int)型 > char型


longとfloatのどちらが精度が良いか?longで表せる整数範囲に限っては十中八九longの方が良いです。

(処理系依存の話ですが一般的なx86PCであれば)long型とfloat型はともに32bit。ただしfloatは浮動小数点の情報分、有効桁数が落ちます。したがってlongの方が高精度なわけです。

つまりここに紹介されている順列は、あくまで暗黙的型変換の順列でしかありません。精度ではありません。

でも今どきの開発環境ならlong -> floatなんて型変換したら警告出るんじゃないかなぁという気もしますが…。


char型の範囲


char型の変数は文字を格納することができますが、-128から127までの値も格納します。

また、unsigned char型の変数は0から255までの値を格納します。


char型はsignedという話ですが、これは処理系依存の話なので誤りです。

符号付き整数が欲しいなら横着しないでsigned charを使おう!charを使うのは危険だぞ!


ポインタ型へのキャスト

#include <stdio.h>


int main(void) {
char str[8] = "Hello";
char *ptr;

// char型ポインタへのキャスト
ptr = (char*)str;
printf("char型ポインタのアドレス先の値は: %s\n", ptr);

return 0;
}


このサンプルコードではchar型の配列「str」をchar型のポインタ「ptr」にキャストして「ptr」のアドレス先の値を表示しています。


その説明はアカン

コードそのものは動きます。動きますが、この説明はどんな変数でもポインタへキャスト出来てしまうかのようです。キャストしたらその変数のアドレスを指すポインタになると。

そんなわけがない

いや確かにキャスト自体はできたりするよ?思った通りには動かないけどな!

このキャストが有効なのは、あくまで配列型はポインタ型に暗黙的型変換が可能という言語仕様によるもの1です。一般の型がポインタ型にキャスト出来るわけではありません。


まとめ

やっぱり侍エンジニア塾はgmですね。





  1. 最初はここに「配列変数は実質ポインタ」という様な誤った情報を書いておりましたので、修正させて頂きました。コメントにて指摘をして下さった方々にお礼を申し上げます。