【C言語】
整数表現で int より狭いchar/short型を多用すると
符号拡張の事故にあう

warning: conversion to ‘size_t’ from ‘short’ may change the sign of the result

警告:shortからsize_tに変換すると結果の符号が変わる可能性がある
[-Wsign-conversion]
[-Wconversion]

■昔メモリの1byteは血の一滴

昔メモリの1byteは血の一滴とする時代があって、
整数を表現する際もint型ではなくて狭い型のchar/short型を多用していました。

今でもこの文化を継承しているプロジェクトは多々ありますが、
桁あふれや符号拡張等の面倒くさい事故にあうリスクが増えるので
メモリをケチるのは止めましょう

というか、狭い型のchar/short型を多用してもメモリ節約にならない事を理解しましょう。


■メモリをケチってメモリ破壊

#include    <string.h>
int main(void)
{
    char    buf[0x8000] ;
    short   size = 0x8000; 
    memset(buf,0,size); //NG:異常終了する
}

short型で0x8000を表現できず0x8000を代入すると負値になります。

memset()の第三引数はsize_t型にもかかわらずshort型を使用したため
型変換(符号拡張)が発生し
0x8000 ではなくて
0xFFFF8000がmemset()に渡ります。

memset()に0xFFFF8000という非常に大きな値が渡ったため領域外破壊が発生し多くの場合プログラムは異常終了します。

注意:
gcc -Wall -Wextra だけでは警告は出ません。
[-Wsign-conversion]
[-Wconversion]を追加指定して下さい。

■メモリをケチって無限ループ事故

#include    <stdio.h>
typedef unsigned char   U1;
typedef unsigned int    U4;
static void f(U4 max) {
    for(U1 i = 0 ; i < max;i++){
        printf("%d\n",i);
    }
}
int main(void) {
    f(256);
}

このコードは
gcc -Wallでも
clang -Weverythingでも警告が出ませんが
U1型では256を表現できないので
無限ループします。

参考:

C-FAQ 1.1: どの整数型を使えばよいか、どうやって決めればよいか。

http://www.kouno.jp/home/c_faq/c1.html#1

int よりも狭いビット幅の型の多用を避ける。

https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/c907.html

INT02-C. 整数変換のルールを理解する

https://www.jpcert.or.jp/sc-rules/c-int02-c.html