<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>鬼の领地 &#187; 微软</title>
	<atom:link href="http://blog.upsuper.org/tag/%e5%be%ae%e8%bd%af/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.upsuper.org</link>
	<description>the place where there are some ghost appearing...</description>
	<lastBuildDate>Wed, 19 Oct 2011 13:21:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>今天写了个小小的 vc-fix</title>
		<link>http://blog.upsuper.org/write-a-little-vc-fix-today/</link>
		<comments>http://blog.upsuper.org/write-a-little-vc-fix-today/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 02:39:51 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[探究学习]]></category>
		<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[VC]]></category>
		<category><![CDATA[兼容性]]></category>
		<category><![CDATA[微软]]></category>
		<category><![CDATA[标准化]]></category>
		<category><![CDATA[编译器]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=1119</guid>
		<description><![CDATA[我们的 C++ 老师给我布置了 C++ 的大作业来替代其他同学交的无聊题目。大作业的第一题就是完整的高精度库，并且要求使用运算符重载。因为原来用 C 写过，这次写，思路上没有太大问题，不过全部程序被我 C++ 化了，代码看过去很诡异……呃…… 我自己的机子上，自然使用 g++ 编译，不过我猜老师会要求 VC6 能够编译……我就用上次安装的 VC6 编译了一下，发现好几个错误和无数警告……其实也是我意料之中的。 其中我觉得最讨厌的莫过于 for 循环的循环变量不被视为 for 循环的局部变量这一点，导致大量变量被其认为是重复定义，这个是 VC6 和标准就语言上相去最远的问题了……不想每个都去改，麻烦死了。 在网上一找，还真找到一个简单的方法： 1 #define for if(0) ; else for 其实我也不知道这个是什么机理，不过真的很管用！ 另外一个就是 VC6 的标准库中没有 max 和 min 函数，这个也很囧，于是也自己写了一个。 以前做网页的时候经常写 ie-fix.css 文件，今天我弄 VC6 遇到这些问题，于是我也写了个 vc-fix.h 文件。M$ 真是一个需要 fix 的公司，什么时候出一个 m$-fix.com 好了…… 最后贴出我的 vc-fix.h，主要解决 VC6 下 [...]]]></description>
			<content:encoded><![CDATA[<p>我们的 C++ 老师给我布置了 C++ 的大作业来替代其他同学交的无聊题目。大作业的第一题就是完整的高精度库，并且要求使用运算符重载。因为原来用 C 写过，这次写，思路上没有太大问题，不过全部程序被我 C++ 化了，代码看过去很诡异……呃……</p>
<p>我自己的机子上，自然使用 g++ 编译，不过我猜老师会要求 VC6 能够编译……我就用<a href="http://blog.upsuper.org/a-simple-script-for-using-vc6-compiler-conveniently/">上次安装的 VC6</a> 编译了一下，发现好几个错误和无数警告……其实也是我意料之中的。<br />
<span id="more-1119"></span><br />
其中我觉得最讨厌的莫过于 for 循环的循环变量不被视为 for 循环的局部变量这一点，导致大量变量被其认为是重复定义，这个是 VC6 和标准就语言上相去最远的问题了……不想每个都去改，麻烦死了。</p>
<p>在网上一找，还真找到一个简单的方法：</p>

<div class="wp_codebox"><table><tr id="p11194"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1119code4"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#define for if(0) ; else for</span></pre></td></tr></table></div>

<p>其实我也不知道这个是什么机理，不过真的很管用！</p>
<p>另外一个就是 VC6 的标准库中没有 max 和 min 函数，这个也很囧，于是也自己写了一个。</p>
<p>以前做网页的时候经常写 ie-fix.css 文件，今天我弄 VC6 遇到这些问题，于是我也写了个 vc-fix.h 文件。M$ 真是一个需要 fix 的公司，什么时候出一个 m$-fix.com 好了……</p>
<p>最后贴出我的 vc-fix.h，主要解决 VC6 下 for 循环变量的问题和 max、min 函数未定义的问题：</p>

<div class="wp_codebox"><table><tr id="p11195"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
</pre></td><td class="code" id="p1119code5"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#ifndef _H_UPSUPER_VC_FIX_</span>
<span style="color: #339900;">#define _H_UPSUPER_VC_FIX_</span>
&nbsp;
<span style="color: #339900;">#ifdef _MSC_VER</span>
<span style="color: #339900;">#   if _MSC_VER &lt;= 1200</span>
<span style="color: #339900;">#       define for if (0); else for</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> max<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> a, <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> b<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> a <span style="color: #000080;">&gt;</span> b <span style="color: #008080;">?</span> a <span style="color: #008080;">:</span> b<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> min<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> a, <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> b<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> a <span style="color: #000080;">&lt;</span> b <span style="color: #008080;">?</span> a <span style="color: #008080;">:</span> b<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T, <span style="color: #0000ff;">class</span> Compare<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> max<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> a, <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> b, Compare comp<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> comp<span style="color: #008000;">&#40;</span>a, b<span style="color: #008000;">&#41;</span> <span style="color: #008080;">?</span> b <span style="color: #008080;">:</span> a<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T, <span style="color: #0000ff;">class</span> Compare<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> min<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> a, <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span> b, Compare comp<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> comp<span style="color: #008000;">&#40;</span>a, b<span style="color: #008000;">&#41;</span> <span style="color: #008080;">?</span> a <span style="color: #008080;">:</span> b<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #339900;">#   endif</span>
<span style="color: #339900;">#endif</span>
&nbsp;
<span style="color: #339900;">#endif // _H_UPSUPER_VC_FIX_</span></pre></td></tr></table></div>

<p>最后要解决的就是警告的问题。其实我很无语的是，所有的警告都是在 VC6 自己的头文件里面的……VC6 自己提示可以添加 /GX 来消除那些警告。于是我不得不再次修改我的编译脚本：</p>

<div class="wp_codebox"><table><tr id="p11196"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code" id="p1119code6"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># - * - coding: UTF-8 - * -</span>
&nbsp;
<span style="color: #007800;">VC6_DIR</span>=<span style="color: #ff0000;">&quot;这里写上VC6的安装地址&quot;</span>
&nbsp;
<span style="color: #007800;">BIN</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$VC6_DIR</span>/VC98/Bin&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">INCLUDE</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$VC6_DIR</span>/VC98/Include&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">LIB</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$VC6_DIR</span>/VC98/Lib&quot;</span> 
&nbsp;
<span style="color: #007800;">ARGS</span>=
&nbsp;
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">getopts</span> <span style="color: #ff0000;">&quot;o:cG:&quot;</span> optname
<span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$optname</span>&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
    <span style="color: #ff0000;">&quot;o&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #007800;">ARGS</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$ARGS</span> /o<span style="color: #007800;">$OPTARG</span>&quot;</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #ff0000;">&quot;c&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #007800;">ARGS</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$ARGS</span> /c&quot;</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #ff0000;">&quot;G&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #007800;">ARGS</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$ARGS</span> /G<span style="color: #007800;">$OPTARG</span>&quot;</span>
    <span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
wine <span style="color: #ff0000;">&quot;<span style="color: #007800;">$BIN</span>/CL.EXE&quot;</span> <span style="color: #007800;">$ARGS</span> <span style="color: #800000;">${@:$OPTIND}</span></pre></td></tr></table></div>

<p>到了最后，再补充一点点吧。VC6 发现了两个额外的错误，我觉得应该不是不兼容的问题。就是我重载的 operator++ 和 operator&#8211; 不小心忘记写 return *this; 了，g++ 没有给我任何提示的编译通过了，而 VC6 则将这个视为错误。</p>
<p>在这个问题上，我同意 VC6 的看法，虽然我怀疑可能 g++ 自己加上了那句话，不过我觉得这个应该至少给出一个警告而非什么都不说。当然，可能一个 fatal error 太过了点……</p>
<p>参考资料：</p>
<ul>
<li><a href="http://www.rugesy.cn/it/u20091012_22_34fe5127-ddfe-44fe-86f1-13afc360a794.html">VC6中FOR语句的变量声明问题</a> 回复的7楼</li>
<li><a href="http://topic.csdn.net/t/20041101/19/3511737.html">如何在程序调试阶段，判断当前的编译器是vc6的编译器还是intel8.0的编译器？ &#8211; CSDN社区</a></li>
<li><a href="http://www.cplusplus.com/reference/algorithm/max/">max &#8211; C++ Reference</a></li>
<li><a href="http://panpan.blog.51cto.com/489034/103074/">VC6.0不支持标准库函数max和min &#8211; C++技术 &#8211; 51CTO技术博客</a></li>
<li><a href="http://topic.csdn.net/t/20040909/19/3357414.html">warning C4530:C++ exception handler used, but unwind semantics are not enabled. Specify -GX &#8211; CSDN社区</a></li>
<li><a href="http://baike.baidu.com/view/1276757.html">_MSC_VER_百度百科</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/write-a-little-vc-fix-today/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>跨编译器的 C 语言 NaN 支持 (纠正)</title>
		<link>http://blog.upsuper.org/nan-support-for-cross-compiler-of-c/</link>
		<comments>http://blog.upsuper.org/nan-support-for-cross-compiler-of-c/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 11:19:59 +0000</pubDate>
		<dc:creator>upsuper</dc:creator>
				<category><![CDATA[雕虫小技]]></category>
		<category><![CDATA[C/C++/C#]]></category>
		<category><![CDATA[VC]]></category>
		<category><![CDATA[兼容性]]></category>
		<category><![CDATA[宏]]></category>
		<category><![CDATA[微软]]></category>
		<category><![CDATA[标准化]]></category>
		<category><![CDATA[编译器]]></category>

		<guid isPermaLink="false">http://blog.upsuper.org/?p=933</guid>
		<description><![CDATA[之前的版本犯了一个重大的错误！我错了……没有经过认真的实验就贴出来…… 正文开始前，先看一个式子： 1 x != x 大家觉得，这个东西的返回可能为 true 么？事实上是可能的，只要这个 x 是 NaN，并且这个 C 编译器符合 IEEE 754 的标准。 所谓 NaN，即 Not A Number，不是一个数。这是 IEEE 754 国际浮点数运算标准当中规定的一个特殊值，这个值由于不是一个数，所以有很多奇怪的特性，比如上面这个不等于其本身。 虽然有这么个东西，而且是国际标准，不过我们也知道，这世界上总有那么些公司是不喜欢理会国际标准的，邪恶的 M$ 就是其中之一。而 Visual C++ 6.0 的 C 编译器也就“有幸”成为了少有的不能完全兼容 IEEE 754 的编译器之一。 至此，我们发现一个问题：邪恶的 M$ 的东西中，总是最垃圾的流传的最广，IE6 如此，VC6 也是如此。另外，在此声明一下，这里讲的全部是 C，不是 C++，在 C++ 中另外有一些比较符合标准的方式同时被各个编译器兼容。 OK，回归正题，既然 VC6 的编译器是个渣，可我们有的时候还是不得不让自己的代码与之兼容，于是就有了各种解决办法。 首先明确一下，我们现在需要两样东西，一是一个可以用于赋值的 NaN (在我的程序中作为一个标记值使用)，另一个是一个用于判断一个数是否为 NaN 的函数或宏。基于上面对 NaN [...]]]></description>
			<content:encoded><![CDATA[<p><strong style="color: red;">之前的版本犯了一个重大的错误！我错了……没有经过认真的实验就贴出来……</strong></p>
<p>正文开始前，先看一个式子：</p>

<div class="wp_codebox"><table><tr id="p93314"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p933code14"><pre class="c" style="font-family:monospace;">x <span style="color: #339933;">!=</span> x</pre></td></tr></table></div>

<p>大家觉得，这个东西的返回可能为 true 么？事实上是可能的，只要这个 x 是 NaN，并且这个 C 编译器符合 IEEE 754 的标准。</p>
<p>所谓 NaN，即 Not A Number，不是一个数。这是 IEEE 754 国际浮点数运算标准当中规定的一个特殊值，这个值由于不是一个数，所以有很多奇怪的特性，比如上面这个不等于其本身。</p>
<p>虽然有这么个东西，而且是国际标准，不过我们也知道，这世界上总有那么些公司是不喜欢理会国际标准的，邪恶的 M$ 就是其中之一。而 Visual C++ 6.0 的 C 编译器也就“有幸”成为了少有的不能完全兼容 IEEE 754 的编译器之一。</p>
<p>至此，我们发现一个问题：邪恶的 M$ 的东西中，总是最垃圾的流传的最广，IE6 如此，VC6 也是如此。另外，在此声明一下，这里讲的全部是 C，不是 C++，在 C++ 中另外有一些比较符合标准的方式同时被各个编译器兼容。</p>
<p>OK，回归正题，既然 VC6 的编译器是个渣，可我们有的时候还是不得不让自己的代码与之兼容，于是就有了各种解决办法。<br />
<span id="more-933"></span><br />
首先明确一下，我们现在需要两样东西，一是一个可以用于赋值的 NaN (在我的程序中作为一个标记值使用)，另一个是一个用于判断一个数是否为 NaN 的函数或宏。基于上面对 NaN 的介绍，在一个符合标准的编译器上，我们可以很容易地给出如下宏：</p>

<div class="wp_codebox"><table><tr id="p93315"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p933code15"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define NaN (0.0 / 0.0)</span>
<span style="color: #339933;">#define IsNaN(x) ((x) != (x))</span></pre></td></tr></table></div>

<p>对于上面这样的 NaN 定义，VC6 不同寻常的会发生编译错误：</p>

<div class="wp_codebox"><table><tr id="p93316"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p933code16"><pre class="text" style="font-family:monospace;">error C2124: divide or mod by zero</pre></td></tr></table></div>

<p>可能也有人会问，难道除 0 不应该是错误么？事实上 IEEE 754 里面就是规定 0.0 / 0.0 = NaN。这里我给出一个我个人的理解：学过高等数学的人大约都会知道，一个无穷小除以一个无穷小，他们的极限可能是无穷大或任何实数，而由于浮点数的精度限制，这里的 0 可能不是真的 0，而是一个很小很小极其趋近于 0 的数，类似无穷小，于是有这样的规定吧。再来看看 IsNaN，这个宏就更无敌了，VC6 的编译器会自作聪明的直接把它优化为 false……</p>
<p>那么对于 VC6 我们该怎么办呢？</p>
<p>查阅了许多资料，最后我们在 MSDN 中翻出了一份年代久远的文档：<a href="http://msdn.microsoft.com/en-us/library/aa298428%28VS.60%29.aspx">_isnan</a>。这里的 _isnan 是 VC6 在 float.h 中定义的一个函数，用于校验一个数是否为 NaN。现在的问题就剩下，我们如何生成 NaN，以及如何判断编译器呢？</p>
<p>那么我们来思考一下，除了用零除零，还有什么方法可以生成 NaN 呢？翻看了 <a href="http://www.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF">IEEE754 标准文档</a>，看到了开平方一个负数也应该是 NaN。这一点应该很好理解，开平方一个负数应该得到一个虚数，而虚数不是一个实数，所以也就 Not a Number 了~于是最后形成了下面一段预处理指令：</p>

<div class="wp_codebox"><table><tr id="p93317"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p933code17"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#ifdef _FPCLASS_SNAN</span>
<span style="color: #339933;">#include &lt;math.h&gt;</span>
<span style="color: #339933;">#define NaN sqrt(-1)</span>
<span style="color: #339933;">#define IsNaN(x) _isnan(x)</span>
<span style="color: #339933;">#else</span>
<span style="color: #339933;">#define NaN (0.0 / 0.0)</span>
<span style="color: #339933;">#define IsNaN(x) ((x) != (x))</span>
<span style="color: #339933;">#endif</span></pre></td></tr></table></div>

<p>虽然调用 sqrt 可能有效率问题，而且额外的需要引用 math 头文件，不过还算几乎完美地解决了 NaN 跨编译器的兼容性问题~事实证明，这段代码可以通过 VC6 的编译器正确地编译并执行。</p>
<p>另外说一点东西，就是如何在 Linux 下用 VC6 的编译器呢？这个问题我想我解决的其实是不完美的，不过也留在这里吧。</p>
<p>首先我下载了一个免安装版的 VC6，然后解压。接着找到了 VC6/VC98/Bin 目录，里面有非常著名的 VC6 编译器的主程序 CL.EXE 以及连接器 LINK.EXE。对于编译器这种纯运算的程序，wine 的兼容性还是比较优美的。不过需要一个额外的 dll 文件支持：mspdb60.dll，这个文件<a href="http://www.dll-files.com/dllindex/dll-files.shtml?mspdb60">很容易载到</a>，解压到 wine 的系统目录 (~/.wine/drive_c/windows/system32) 就可以了。</p>
<p>接下去就是如何编译了……我的方法比较老土，是将待编译的文件复制到编译器目录，然后执行类似下面命令：</p>

<div class="wp_codebox"><table><tr id="p93318"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p933code18"><pre class="bash" style="font-family:monospace;">wine CL.EXE 源文件.c <span style="color: #000000; font-weight: bold;">/</span>I..<span style="color: #000000; font-weight: bold;">/</span>Include <span style="color: #000000; font-weight: bold;">/</span>o可执行文件.exe <span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">link</span> <span style="color: #000000; font-weight: bold;">/</span>LIBPATH:..<span style="color: #000000; font-weight: bold;">/</span>Lib</pre></td></tr></table></div>

<p>其中“源文件.c”和“可执行文件.exe”是很容易理解的，“/I../Include”是使编译器能知道 include 的文件应该去哪里找，而“/link”表示后面的部分是连接器参数，“/LIBPATH:../Lib”就是表示静态链接库的地址了~</p>
<p>最后再说说如何将 GCC 可以编译的程序移植到 VC6 中。GCC 实现了 C99 标准，但 VC6 因为出现在 1998 年 (怎么正好早一年……不过就算是 99 年出也未必会支持 C99 就是了……)，所以不支持 C99，于是所有的变量必须在函数最前面声明，不能混入代码内部。此外，在 VC6 当中，void 指针是不能进行运算的。还有就是不能用“//”开头的行注释，必须使用块注释。这是我移植过程中遇到的主要麻烦。</p>
<p>事实上，在 GCC 当中，可以验证大多数 C89 的限制，只要在编译的时候用如下语句：</p>

<div class="wp_codebox"><table><tr id="p93319"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p933code19"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">gcc</span> <span style="color: #660033;">-ansi</span> <span style="color: #660033;">-pedantic</span> <span style="color: #660033;">-o</span> 可执行文件 源文件.c</pre></td></tr></table></div>

<p>只要把其中所有的 warning 全部消灭掉就可以啦~</p>
<p>当然，最好的方法莫过于在 VC6 的编译器中直接测试了……</p>
<p>最后最后，M$ 实在是……唉……这个世界上不明真相的孩子果然是占大多数的……</p>
<hr />
<p>关于修改的部分：之前的版本错误的使用 _FPCLASS_SNAN 这一校验函数 _fpclass 返回值当作 NaN 来使用。既然查到了这个，这里也顺便说一下这个东西吧。在 VC 的 float.h 库里面有 _fpclass 这个函数，用于检验一个浮点数的类型，可能的返回值都在 float.h 里面，如下：</p>

<div class="wp_codebox"><table><tr id="p93320"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p933code20"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define _FPCLASS_SNAN   0x0001  /* signaling NaN */</span>
<span style="color: #339933;">#define _FPCLASS_QNAN   0x0002  /* quiet NaN */</span>
<span style="color: #339933;">#define _FPCLASS_NINF   0x0004  /* negative infinity */</span>
<span style="color: #339933;">#define _FPCLASS_NN     0x0008  /* negative normal */</span>
<span style="color: #339933;">#define _FPCLASS_ND     0x0010  /* negative denormal */</span>
<span style="color: #339933;">#define _FPCLASS_NZ     0x0020  /* -0 */</span>
<span style="color: #339933;">#define _FPCLASS_PZ     0x0040  /* +0 */</span>
<span style="color: #339933;">#define _FPCLASS_PD     0x0080  /* positive denormal */</span>
<span style="color: #339933;">#define _FPCLASS_PN     0x0100  /* positive normal */</span>
<span style="color: #339933;">#define _FPCLASS_PINF   0x0200  /* positive infinity */</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.upsuper.org/nan-support-for-cross-compiler-of-c/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

