ことの始まりは、Qt のビルドから。
一応、gcc-4.8.2 ではビルドできたし、qtconfig
などはちゃんと動いている。OpenGL でプログラムを作成する用事があった (実際には Qt ではなく Windows Forms なのだが…) ので、その Qt で練習していた分には問題なかった。しかし、desinger
や qtdemo
は動かなかった。
$ /opt/kde/bin/designer
Segmentation Fault (core dumped)
何が原因かよく分からないので、clang
でもビルドしてみることにした (Qt では clang でのビルドは unsupported 扱いになっているが…)。
その辺はあくまで発見した経緯で、問題になったのは次のソースを C++ としてコンパイルした場合。
#include <stdlib.h>
#include <math.h>
int main() {
return 0;
}
もちろん(?)、g++
では問題なく通る。これを clang++
でコンパイルすると、…
/usr/include/floatingpoint.h:204:15: error: declaration conflicts with target of
using declaration already in scope
extern double atof __P((const char *));
^
/usr/include/iso/stdlib_iso.h:124:15: note: target of using declaration
extern double atof(const char *);
^
/usr/include/stdlib.h:52:12: note: using declaration
using std::atof;
^
(atof
のほか strtod
に対しても出る)
ちなみに、stdlib.h
→cstdlib
、math.h
→cmath
としても変わらず (libstdc++
、libc++
ともに)。
また、stdlib.h
と math.h
の include 順を変えた場合は通る。
何が問題って、何で math.h
(の中の floatingpoint.h
) で atof
(や strtod
) を宣言しているのかっていう点と、cstdlib
でもないのに、std::atof
と std
名前空間の中に閉じ込めて using
で global からも呼び出せるようにしているのかという点。
ちなみに、string.h
と sys/socket.h
でも起こる。
どちらも __EXTENSIONS__
の定義が無ければ回避できるが、かなりの量の宣言が消えるので、たとえコンパイルが通ったとしても、それはそれで問題がある。
/opt/llvm/3.4/include/c++/v1/cstdio:148:9: error: no member named 'vfscanf' in
the global namespace; did you mean 'fscanf'?
using ::vfscanf;
~~^
(※ vfscanf
は C++11 では宣言されているはずであるが、OpenIndiana では対応していない。)
だから、floatingpoint.h
とか普通使わない拡張機能のヘッダを math.h
を読む前にあらかじめ読んで、別の名前空間に入れてしまえば一応解決できる(?)。
#include <stdlib.h>
namespace _fp {
extern "C" {
#include <floatingpoint.h>
}
}
#include <math.h>
sys/socket.h
の方はこんな感じ。
#include <string.h>
namespace _sys_un {
extern "C" {
#include <sys/un.h>
}
}
using _sys_un::sa_family_t;
#include <sys/socket.h>
ちなみに Qt では mutex
という名前の変数 (QMutex
型) を使っているが、sys/mutex.h
で構造体の名前として使われているため、それの回避も。
namespace _sys_mut {
extern "C" {
#include <sys/mutex.h>
}
}
using _sys_mut::kmutex_t;
あれ、でもそれって本来問題ない様な…