Skip to content

Instantly share code, notes, and snippets.

@iwadon
Last active December 15, 2015 20:19
Show Gist options
  • Save iwadon/5317358 to your computer and use it in GitHub Desktop.
Save iwadon/5317358 to your computer and use it in GitHub Desktop.
Object.GetType()を呼び出さないとうまく動かないところが納得いかない。 → QA@ITに質問してみた。http://qa.atmarkit.co.jp/q/2834 → Monoの不具合だった。 → ushortからshortでの不具合は修正された。 → boolからsbyteでの不具合が見つかった。
/tmp.exe
/tmp2.exe

自前ビルドしたC#コンパイラでコンパイルするとうまく動かないコードがある。

(tmp2.csを挿入)

うまく動かない場合はすべてにおいてFalseとなる。

value(-64) <     -1 => False
value(-64) <  -0x20 => False
value(-64) <  -0x80 => False

本来次のような結果になるはず。

value(-64) <     -1 => True
value(-64) <  -0x20 => True
value(-64) <  -0x80 => False

これは何が起きているのだろうか?

問題のないコンパイラ

csc.exe

Microsoft (R) Visual C# Compiler Version 4.0.30319.17929
for Microsoft (R) .NET Framework 4.5
Copyright (C) Microsoft Corporation. All rights reserved.

Mac OS X版3.0.6 (公式配布物)

Mono JIT compiler version 3.0.6 (master/20e40c4 Wed Feb 27 10:15:23 EST 2013)
Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           normal
        SIGSEGV:       altstack
        Notification:  kqueue
        Architecture:  x86
        Disabled:      none
        Misc:          softdebug 
        LLVM:          yes(3.1svn-mono)
        GC:            Included Boehm (with typed GC)

ideon.com (mono-2.8)

See http://ideone.com/SU6Ma0

問題が起きるコンパイラ

FreeBSD ports lang/mono (Mono 3.0.3) on FreeBSD 9.1-STABLE

Mono JIT compiler version 3.0.3 (tarball Fri Apr 19 16:54:49 JST 2013)
Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notification:  kqueue
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            Included Boehm (with typed GC and Parallel Mark)

自前ビルド版3.0.6 on FreeBSD 9.1-STABLE

Mono JIT compiler version 3.0.6 (mono-3.0.6/20e40c4 2013年 4月19日 金曜日 20時21分40秒 JST)
Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       normal
        Notification:  kqueue
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            Included Boehm (with typed GC and Parallel Mark)

自前ビルド版3.0.6 on Mac OS X 10.7.5

Mono JIT compiler version 3.0.6 (mono-3.0.6/20e40c4 2013年 4月19日 金曜日 20時57分05秒 JST)
Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           normal
        SIGSEGV:       altstack
        Notification:  kqueue
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug 
        LLVM:          supported, not enabled.
        GC:            Included Boehm (with typed GC)

自前ビルド版3.0.10 on FreeBSD 9.1-STABLE

Mono JIT compiler version 3.0.10 (master/1c94cd3 2013年 4月19日 金曜日 19時24分22秒 JST)
Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       normal
        Notification:  kqueue
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            Included Boehm (with typed GC and Parallel Mark)

Tested environments:

  • Mono JIT compiler version 3.0.3 (tarball Thu Apr 11 19:43:51 JST 2013) from FreeBSD ports on FreeBSD 9.1-STABLE
  • Mono JIT compiler version 3.0.6 (master/20e40c4 Wed Feb 27 10:15:23 EST 2013) from Official release on Mac OS X 10.7.5
  • Mono JIT compiler version 3.0.10 (master/add2135 2013年 4月12日 金曜日 14時20分10秒 JST) from GitHub on FreeBSD 9.1-STABLE

See QA@IT/2834: http://qa.atmarkit.co.jp/q/2834

Tested online services:

#!/bin/sh
set -e -x
if [ $# == 0 ]; then
echo "Usage: $0 BRANCH"
exit 1
fi
branch_name=$1
case $branch_name in
master)
prefix=$HOME/local/stow/mono-git;
;;
mono-*)
prefix=$HOME/local/stow/$1;
;;
*)
echo "Invalid branch name: $1";
exit 1
;;
esac
jobs=`sysctl hw.ncpu | awk '{print $2}'`
case `uname` in
FreeBSD)
make=gmake
;;
*)
make=make
;;
esac
git reset --hard
if git branch | grep -e " $branch_name\$"; then
git co $branch_name
else
git co -b $branch_name $branch_name
fi
git reset --hard
git submodule init
git submodule update
case `uname` in
FreeBSD)
patch -p0 < /usr/ports/lang/mono/files/patch-mono_io-layer_sockets.c
;;
*)
;;
esac
NOCONFIGURE=1 ./autogen.sh
rm -rf _build_
mkdir _build_
cd _build_
../configure --prefix=$prefix --without-x --disable-nls
$make -j$jobs
rm -rf $prefix/$branch_name
$make -j$jobs install
#stow -d $HOME/local/stow -R $branch_name
#!/bin/sh
set -e
#mcs tmp.cs
#mono tmp.exe
mcs tmp2.cs
mono tmp2.exe
using System;
using System.Reflection;
namespace Tmp
{
public class Packer
{
public Packer()
{
}
public void PackUInt16(ushort value)
{
}
public void PackInt16(short value)
{
//value.GetType();
Console.WriteLine("value({0}) < -0x80 => {1}", value, value < -0x80);
Console.WriteLine("value({0}) < -0x20 => {1}", value, value < -0x20);
Console.WriteLine("value({0}) < 0x80 => {1}", value, value < 0x80);
Console.WriteLine("value({0}) < 0x100 => {1}", value, value < 0x100);
}
public void PackObject<T>(T obj)
{
Type this_type = this.GetType();
string obj_type_name = obj.GetType().ToString();
string method_name = "Pack" + obj_type_name.Substring(obj_type_name.LastIndexOf(".") + 1);
//Console.WriteLine(method_name);
MethodInfo mi = this_type.GetMethod(method_name);
mi.Invoke(this, new object[] { obj });
}
public static void Main()
{
Packer packer = new Packer();
packer.PackObject((ushort)0);
packer.PackObject((short)-1);
}
}
}
using System;
using System.Reflection;
namespace Tmp
{
public class Packer
{
public Packer()
{
}
public void PackBoolean(bool value)
{
}
public void PackSByte(sbyte value)
{
//value.GetType();
Console.WriteLine("value({0}) < -1 => {1}", value, value < -1);
Console.WriteLine("value({0}) < -0x20 => {1}", value, value < -0x20);
Console.WriteLine("value({0}) < -0x80 => {1}", value, value < -0x80);
}
public void PackObject<T>(T obj)
{
Type this_type = this.GetType();
string obj_type_name = obj.GetType().ToString();
string method_name = "Pack" + obj_type_name.Substring(obj_type_name.LastIndexOf(".") + 1);
//Console.WriteLine(method_name);
MethodInfo mi = this_type.GetMethod(method_name);
mi.Invoke(this, new object[] { obj });
}
public static void Main()
{
Packer packer = new Packer();
packer.PackObject(true);
packer.PackObject((sbyte)-0x40);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment