Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Macのg++とopen64

タグ: Mac C++ gcc

Linux向けに作成中のコードをMacのg++でコンパイルしたところ、以下のエラーが発生した。

error: ‘open64’ was not declared in this scope

どうもMacのopen素で64bitに対応しているため、open64が存在しないらしい。

仕方がないので、コンパイルオプションに

-D_FILE_OFFSET_BITS=64

を加えてopenを64bit化し、open64openに書き換える。

ただこれだけだと本当に64bit化されているか不安(コンパイルオプションを書き間違えるかも……)だったので、念のためコードに静的表明を埋め込む。

BOOST_STATIC_ASSERT(sizeof(off_t) == 8);

これでひとまず安心かな。

本日見かけた酷いコード4

タグ: C++ 酷いコード
struct coord
{
#ifdef BIG_ENDIAN
	short x : 8;
	short y : 8;
#else
	short y : 8;
	short x : 8;
#endif
};

ビットフィールドというものは、互換性を考えるとなかなかに面倒な仕組みである。

まず、ビットフィールドで使える型は、JISX3010:2003によると

ビットフィールドの型は、修飾版又は非修飾版の_Bool、signed int、unsigned int又は他の処理系定義の型でなければならない。

とある。

なので処理系で定義されてさえいればshort型も使えるわけだが、しかしわざわざそのような型を使うことにどれほどの意味があろう。
ここは素直にsigned intかunsigned intを使っておけば良い。

なお、ビットフィールドでは「intの挙動も処理系定義」である。

ただし、ビットフィールドの場合、型指定子intがsigned intと同じ型を表すか、unsigned intと同じ型を表すかは処理系定義とする。

「符号付き整数型であることは保証されていない」ので注意。

そしてさらに気をつけなければならないのは、「ビットフィールドの並びがバイトオーダーで一意に求まるわけではない」ということ。
ビットフィールドの並びは、規格では以下のようにある。

単位内のビットフィールドの割付けの順序(上位から下位か又は下位から上位か)は、処理系定義とする。

特定の処理系でバイトオーダーとビットオーダーの関係を調べたとしても、それが他の処理系でも通用するかは判らない。
そのため、バイナリ互換が必要な場面でビットフィールドを使うのは何かと危険である。

もっとも。
このコードに関して言えば、以上のようなビットフィールドに関する細かい話はどうでもよく、ただ

struct coord
{
	char x;
	char y;
};

こうすればいいじゃないか、というだけのことなのだが。

本日見かけた酷いコード3

タグ: C++ 酷いコード
void func(void* src, int word_offset)
{
	// 2バイト単位でシークするためshortのポインタを使う
	short* p = reinterpret_cast<short*>(src);
	p += word_offset;
	p += sizeof(long);

これで正常に動作しているのだから間違ってはいないのだろうが……どう見ても「pをcharポインタと間違えている(1バイト単位でシークさせようとしている)」ようにしか見えない。

8バイト進めたいのなら素直に

p += 4;

と書けばいいのに。
(shortポインタの時点で既に素直じゃないが)

切り貼りの世界で

JASRACは「放送通信融合」の敵か味方か--菅原常任理事に聞く(CNET Japan)

あくまで事務的であるという点に非はない。
特例とか設けられたらかえって面倒なことになるだろう。

しかし

続きを読む

ClearCaseで特定のラベルが付いたファイルを参照する

タグ: ClearCase

ClearCaseも使ってみると面白いけど、TortoiseSVNに慣れた身にはいろいろときつい。
だがそこにソースが置かれている以上使わざるを得ないわけで……

とりあえず今日は特定のラベルが付けられたファイルだけ参照する方法を知ったのでメモ。

続きを読む

169.254.x.x

タグ: Mac

外出から帰ってきてMacBook Proのスリープを解除したら、ネットワークの状態が

“内蔵 Ethernet”に自己割り当ての IP アドレスが設定されており、インターネットに接続できない可能性があります。

となっていて、文面通りインターネット(及びLAN内の他機器)に接続できなくなっていた。

続きを読む

本日見かけた酷いコード2

タグ: C++ 酷いコード
// 構造体の中身は適当に簡略化
struct foo
{
	int val;
};

// こっちも簡略化
struct bar
{
	int val;
};

// qsortみたいな関数のコールバック
int comp(const void* lhs, const void* rhs)
{
	foo* p1;
	bar* p2;
	
	p1 = reinterpret_cast<foo*>(const_cast<void*>(lhs));
	p2 = reinterpret_cast<bar*>(const_cast<void*>(rhs));
	
	if(p1->val < p2->val)
		return -1;
	if(p1->val > p2->val)
		return 1;
	else
		return 0;
}

さすがに前回ほどの衝撃はなく、いたって普通のダメコード。

普通に書いたらこんな感じになるだろう。

	const foo* p1 = static_cast<const foo*>(lhs);
	const bar* p2 = static_cast<const bar*>(rhs);

書き方から推察するに、最初はC形式のキャストを使っていたものの、静的解析(QAC)に駄目出しされたため、できるだけアルゴリズムに変更が生じないよう静的解析を誤魔化す方法を模索した結果、この形に至ったものと思われる。
まさか普段からC++形式のキャストを使っている人がconstを付けるよりも剥がす方を優先したりしないだろうし。

しかしまあなんというか、良いコードを書こうと思わない人(あるいはそれを良しとしない環境)にとって、静的解析は宝の持ち腐れだよね……

RV-230NE ファームウェア Version 3.07

IPマスカレードがうまく動作しなくなっていたのでルータの様子を確認しにいったら、新しいファームウェアが公開されているのを発見。
再起動ついでに更新する。

続きを読む

R-Side

鏡音リンのデモソングが公開された

聴いてすぐ「おお、亜美真美の声だ」と感心したが、コメントを見ると「ミクと区別が付かない」という意見が意外と多い。
私の聴き方だとミクとリンは「声質的には」別物なのだが、聴き手によってはそうでもないか、あるいは期待していた差異の存在を確認できなかったらしい。

確かに、ミクとリンは同世代のVOCALOIDだし、技術的な進歩はさほどないから、その独特の機械臭さは変わらない。
それが耳に付く人にとって、両者は同じようなものなのかもしれない。

Boost Vault Endian

タグ: C++ Boost

構造体をそっくりそのままバイナリデータとして読み込んだり保存しなければならないときに重宝するライブラリ。
メンバ変数をこのライブラリの型で表すだけで、保存先データと実行環境のエンディアンの違いを吸収する。

試しにlzhファイルのヘッダを読んでみる。

#include <iostream>
#include <fstream>
#include <string>
#include <boost/integer/endian.hpp>

using namespace boost::integer;

#pragma pack(push, 1) // 念のため
struct lha2_header
{
	little16_t hedsize;
	little8_t method[5];
	little32_t packed;
	little32_t original;
	little32_t time;
	little8_t attrib;
	little8_t level;
	little16_t filecrc;
	little8_t OSmark;
};
#pragma pack(pop)

int main(int argc, char** argv)
{
	if(argc < 0)
		return 1;
	
	std::ifstream ifs(argv[1],std::ios::in | std::ios::binary);
	
	lha2_header h;
	ifs.read(reinterpret_cast<char*>(&h), sizeof(h));

	std::cout << "hedsize:" << static_cast<unsigned int>(h.hedsize) << std::endl;
	std::cout << "method:" << std::string(reinterpret_cast<char*>(h.method), 5) << std::endl;
	std::cout << "OSmark:" << static_cast<char>(h.OSmark) << std::endl;

	return 0;
}

実行結果


hedsize:48
method:-lhd-
OSmark:M

……ってIntel Macじゃ試しになってないな。

gccでInterlockedIncrement

タグ: C++ gcc

Win32 SDKの InterlockedIncrement() みたいなものはgccには用意されていないのだろうかと探してみたら、 boost/detail/atomic_count_gcc.hpp で使われているのを見つけた。

忘れないうちにメモ。

#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
# include <ext/atomicity.h>
#else
# include <bits/atomicity.h>
#endif

#if defined(__GLIBCXX__) // g++ 3.4+
using __gnu_cxx::__atomic_add;
using __gnu_cxx::__exchange_and_add;
#endif

int main(int argc, char** argv)
{
	_Atomic_word val = 10;
	
	// 値を増減させる
	__atomic_add(&val, 2);
	// val == 12

	// 値を増減させて、増減させる前の値を返す	
	_Atomic_word old = __exchange_and_add(&val, -4);
	// val == 8
	// old == 12

MacでMercurialを使ってみたが……

タグ: Mac Mercurial

MacPortsにMercurialがあったので入れてみる。

続きを読む

角川と動画配信

「YouTubeは世界共通語」――角川会長の考える“次の著作権”

……んー

こんなこともあったよねー( ´∀`)σ)Д`)

続きを読む

らき☆すたRe-Mix002

らき☆すたRe-Mix002?『ラキスタノキワミ、アッー』【してやんよ】?

……なんの冗談かと思った。

enumの前方宣言

タグ: C++

VC6向けのコードをgccでコンパイルしていたところ、「enumの前方宣言」を行っている個所がエラーとなった。

enumの前方宣言は今回初めて目にしたので、せっかくだから規格上本当に不可能なものなのかを確認しておく。

続きを読む

gccの不思議な警告

タグ: gcc C++
#include <iostream>

int main(int argc, char* argv[])
{
	const int dec = -263716858L;
	const int hex = 0xf0480006L;

	const int expr = 0xf0480006L;
	
	switch(expr)
	{
	case dec:
		std::cout << dec << std::endl;
	}

	switch(expr)
	{
	case hex:
		std::cout << hex << std::endl;
	}

	return 0;
}

このコードをgccでコンパイルすると

hoge.cpp: function 内の `int main(int, char**)':
hoge.cpp:18: 警告: 暗黙の定数変換でオーバーフローしました

こんな警告が表示された。

続きを読む

LS-LGLシリーズ ファームウェア アップデータ Ver.1.03

2007/11/26付けで新しいのが出ていたのでダウンロード。
……/M(Mac向け)と共用のファームウェアなのにexeしかないのか。

サービスステーション

富士フイルムのサービスステーション近くに行く用事ができたので、母から「写りがおかしくなった」ということで預かっていたFinePix F401を持って行く。

続きを読む

本日見かけた酷いコード

タグ: C++ 酷いコード
struct Data { /* 略 */ };

struct List
{
	short count;
	Data* data;
};

struct Buffer
{
	char list[sizeof(List)];
	char array[sizeof(Data)*1000];
	char names[1000][31];
};
   _, ._
 ( ゚ Д゚)   ………??
 ( つ旦O
 と_)_)
// calloc_buffer() は calloc(sizeof(Buffer)) のような関数
Buffer* buffer = reinterpret_cast<Buffer*>(calloc_buffer());
List* list = reinterpret_cast<List*>(buffer->list);
list->data = reinterpret_cast<Data*>(buffer->array);
   _, ._
 ( ゚ ◎゚)   ズズ…
 ( ゙ノ ヾ
 と_)_)

   _, ._
 ( ゚ Д゚)   …………
 ( つ旦O
 と_)_)

Appendix

タグ

Blog内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。