53歳限界プログラマの憂鬱

SU/CAR-ST-APplication-cellsから派生したプログラマのブログ

本家はこちら↓
f:id:sucar:20151115183011p:plain

SU/CAR-ST-APplication-cellsの安倍野ミックスと申します
来訪ありがとうございます
シストレツールを自作してます

f:id:sucar:20150414193802p:plain

TckTkのmingwでのビルドがエラーになる件

前にTclTk8.6.6をmingwでビルドした記事を書いた 

abenomix.hatenablog.com

確かにビルドできたしきちんと動いている

ところが別のPCでビルドしたらこけてしまった

違いとしては

  • ビルドできた環境  gcc 4.8.1
  • ビルドできなかった環境  gcc 5.3.0

ちなみに会社のPCのmingwgcc 4.9.3 でこれもビルドがこけた

本当にgcc のバージョンだけが原因かどうかは不明だが、些細な?環境の違いでビルドできたりできなかったりするのは確かです

mingwを今DLしてセットアップすると、gcc 4.8.1にならないので今後のことを考えるとちょっと困った事態になった感じ

ちなみにgcc5.3.0になっちゃったのは mingw-get upgrade を実行したらgccもupgradeされたということです

D:/MinGW32/msys/1.0/home/scr/tcl8.6.6/generic/tclInt.h:115:38: error: 'uintptr_t' undeclared (first use in this function)
# define PTR2UINT(p)((unsigned int)(uintptr_t)(p))
というエラーで

'uintptr_t'なんて知らん 宣言しろボケ

ってgcc様がのたまう

しかし、win/configureは

checking for uintptr_t... yes

って言っている

uintptr_t についてまったくわからなかったがいろいろググってなんとなく理解はできた

32bit 環境と64bit 環境でアドレス幅が違うからその違いを吸収するためにあるらしい

非常に困ったが自力で何とかしてみたので以下参照

 

<解決法1> uintptr_t を消すw

非常に強引だけど、よくわからないながら、uintptr_t さえなければいいのでw

エラーで落ちたとこは

# define UINT2PTR(p) ((void *)(uintptr_t)(p))
# define PTR2UINT(p) ((unsigned int)(uintptr_t)(p))
となっていて2重にキャストしている

なので強引に

# define UINT2PTR(p) ((void *)(p))
# define PTR2UINT(p) ((unsigned int)(p))
としてみるw

結論からいうとこれでビルドは成功し、動作もOKだった

ただ、あまりに強引すぎるので、確認のため

test.c

#include <stdio.h>
#include <stdint.h>

void main(void) {
  printf("%d%d%d\n",sizeof(void*),sizeof(unsigned int),sizeof(uintptr_t));
}

テストプログラムを作って実行してみると

$ gcc test
$ a
444

と全部4(つまり32bit)となるので、一応問題はなさそうである

 

<解決2>

しかし、解決1は気持ち悪いのでちゃんとした解決法がないかいろいろ考えてみたんですが・・・

仮に自作ソースでundeclaredと言われたら原因として何を考えるか?

というと

ヘッダを#includeするのを、つまり #include <stdint.h> 忘れてました

 となるのでまさかと思い調べてみると

tclInt.hの頭に

#include <stdint.h> 

がないことが判明!

半信半疑で

#include <stdio.h>の次の行に

#include <stdint.h>を追加してみると・・・

無事にビルドできました

これはバグなんだろうか?

でも、それではなぜ gcc4.8.1ではビルドできたのだろうか?

なぞは深まるが解決したからまあいいかw