??xml version="1.0" encoding="utf-8" standalone="yes"?>久久国产精品偷99,欧美精品一区二区精品久久,伊人久久亚洲综合影院http://www.shnenglu.com/ownwaterloo/zh-cnTue, 06 May 2025 20:46:38 GMTTue, 06 May 2025 20:46:38 GMT60C与C++的细微区别——省略Ş式参数名http://www.shnenglu.com/ownwaterloo/archive/2009/04/26/omit_parameter_name.htmlOwnWaterlooOwnWaterlooSun, 26 Apr 2009 07:01:00 GMThttp://www.shnenglu.com/ownwaterloo/archive/2009/04/26/omit_parameter_name.htmlhttp://www.shnenglu.com/ownwaterloo/comments/81117.htmlhttp://www.shnenglu.com/ownwaterloo/archive/2009/04/26/omit_parameter_name.html#Feedback5http://www.shnenglu.com/ownwaterloo/comments/commentRss/81117.htmlhttp://www.shnenglu.com/ownwaterloo/services/trackbacks/81117.html
在函数声明中Q?br>无论是Cq是在C++Q都可以省略形式参数名?br>但是Q通常?strong>?/span>省略形式参数名?br>
在函数定义中Q?br>1. 当需要用Ş式参数的时候,昄Q必ȝ形式参数命名?br>
2. 当不需要用Ş式参数的时候,C与C++有微差异:(x)
—?C不能省略形式参数?/strong>Q?不用?br>—?C++可以省略形式参数?/strong>Q?strong style="COLOR: red">如果不用?br>—?q且在C++中,如果l不使用的Ş式参数命名,可能?x)得C?strong>警告?br>


二、示例:(x)
#include <stdio.h>

void greeting_omit(const char* name);
void greeting_unuse(const char* name);
void greeting_nowarning(const char* name);

int main(void) {
    greeting_omit(
"");
    greeting_unuse(
"");
    greeting_nowarning(
"");
    (
void)getchar();
    
return 0;
}



三、三个函数分别实现如下:(x)

        三?
void greeting_omit(const char* ) {
    printf(
"hello world\n");
}

——在C中是错误Q?br>1. msvc :
error C2055: expected formal parameter list, not a type list
error C2055: 应输入Ş参表Q而不是类型表

2. gcc : Q报错更清晰一些)
error: parameter name omitted
错误Q?省略参数?br>
——在C++中正,且无警告?br>
        三?
void greeting_unuse(const char* name) {
    printf(
"hello Cherrie\n");
}

在C和C++中都正确Q但可能得到一个警告:(x)
1. msvc :
warning C4100: 'name' : unreferenced formal parameter
warning C4100: “name”: 未引用的形参

2. gcc :
warning: unused parameter 'name'
警告Q?未用的参数‘name’

在gcc中,打开q个警告的选项?strong>-Wunused-parameter?br>该选项包含?Wall中?br>
        三?
void greeting_nowarning(const char* name) {
    (
void)name;
    printf(
"hello OwnWaterloo\n");
}

在C和C++中都正确Qƈ且无警告?br>


相关链接Q?br>
——示例代?br>http://immature.googlecode.com/svn/trunk/iMmature/sample/omit_parameter_name



Creative Commons License
?span rel="dc:type" xmlns:dc="http://purl.org/dc/elements/1.1/">作品
采用知识׃n|名-非商业性?相同方式׃n 2.5 中国大陆许可协议q行许可?

转蝲h?Q?br>文章作?- OwnWaterloo
发表旉 - 2009q?4?6?br>原文链接 - http://www.shnenglu.com/ownwaterloo/archive/2009/04/26/omit_parameter_name.html

OwnWaterloo 2009-04-26 15:01 发表评论
]]>
main函数中省略返回语?/title><link>http://www.shnenglu.com/ownwaterloo/archive/2009/04/26/omit_return_in_main.html</link><dc:creator>OwnWaterloo</dc:creator><author>OwnWaterloo</author><pubDate>Sun, 26 Apr 2009 06:37:00 GMT</pubDate><guid>http://www.shnenglu.com/ownwaterloo/archive/2009/04/26/omit_return_in_main.html</guid><wfw:comment>http://www.shnenglu.com/ownwaterloo/comments/81116.html</wfw:comment><comments>http://www.shnenglu.com/ownwaterloo/archive/2009/04/26/omit_return_in_main.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/ownwaterloo/comments/commentRss/81116.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/ownwaterloo/services/trackbacks/81116.html</trackback:ping><description><![CDATA[<p>一、依?br><br>C++标准规定Qmain函数可以省略q回语句Q等效于q回0?br><br>5. A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling exit with the return value as the argument.<br>If control reaches the end of main without encountering a return statement, the effect is that of executing<br>return 0;</p> <p>                ——ISO C++03 3.6.1 Main function p44/72<br>                ——ISO C++98 3.6.1 Main function p43/69<br><br>注意Q?br>1. main函数的返回类型是<strong style="COLOR: #0000ff">int</strong>Q?不是void或者其他类型?br>2. 该规?strong>仅仅</strong>对main函数适用?br>3. 对其他函敎ͼ如果省略q回| 得C?strong>警告</strong>?br>4. 应该<strong>避免</strong>3的情c?br><br><br> <hr width="80%"> <br>二?nbsp;CZ<br><br>        二?. 一个合法的最化的完整C++E序如下Q? <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main() {}</span></div> <br>        二?. 省略的确切含?br><br>同时Q标准中的用语是?strong>考究</strong>的:(x)<br>“当控制到达mainl束处时没有遇到return语句Q效果与q回0相同”?br><br>x_标准规定的是“对省略return?strong style="COLOR: #ff0000">分支</strong>Q认?”?br>同时Q标准也允许<strong>其他分支</strong>含有q回语句?br>如下Q? <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> argc,</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> []) {<br>    </span><span style="COLOR: #0000ff">switch</span><span style="COLOR: #000000"> (argc)<br>    {<br>    </span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:<br>        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> error, should passing argument</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br>        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> parse arguments</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">default</span><span style="COLOR: #000000">:<br>    </span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">: </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> parser argv[2]</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">: </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> parser argv[1]</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">        ;<br>    }<br>    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> do some work<br>    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> control reaches <strong style="COLOR: #ff0000">here</strong></span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">}</span></div> <br>没有输入命o行参数时Q?q回一个错误?br>其他情况Q当控制辑ֈmain?strong>l尾</strong>处时Q效果同return 0;<br><br>        二?. 对于其他函数Q没有这U?#8220;优待”<br>如:(x)<br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> not_main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> argc) {<br>    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (argc</span><span style="COLOR: #000000"><=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br>        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br>}<br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> argc,</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> []) {<br>    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> not_main(argc);<br>}</span></div> <br>not_main无疑得C个警告?br>E序在没有输入命令行参数时的q回值将<strong><span style="COLOR: #ff0000">无法</span>预知</strong>?br><br> <hr width="80%"> <br>三、验?br><br>        三?. ERRORLEVEL<br><br>windows下,可以通过 %<strong>ERRORLEVEL</strong>% 查询上一ơ程序返回倹{?br><br>l果与判断相dQ?br>1. minimalist?strong>定</strong>的返回?<br>2. omit_return_in_main?strong>定</strong>的返回?1?<br>3. 对omit_return_in_other<br>3.1 有命令行参数Ӟq回?strong>定</strong>??br>3.2 无命令行参数Ӟq回?strong><span style="COLOR: #ff0000">无法</span>预知</strong>? <p><br>        三? 汇编代码<br><br>更严谨的验证Ҏ(gu)是查看汇~代码?br><br>可以看到Q在minimalist与omit_return_in_main的main函数中都有将eax|?的代码?br>在omit_return_in_other中的not_main函数中,没有q样的代码?/p> <p><br> <hr width="80%"> <br>四?nbsp;例外<br><br><strong>VC6</strong>在这点上与标准不W?br><br>        四?. 对omit_return_in_mainQ它l出的警告:(x)<br><br>warning C4715: 'main' : not all control paths return a value<br><br>说明它在q点上与标准不符?br>昄Q在有命令行参数的时候,E序l果<strong><span style="COLOR: #ff0000">无法</span>预知</strong>?br><br><br>        四?. 对minimalistQ它l出的警告很搞笑Q?br><br>warning C4508: 'main' : function should return a value; <strong>'void' return type <span style="COLOR: #ff0000">assumed</span></strong><br><br>暴露出它另一?strong>与标准不W?/strong>的地方——mainq回void?br>昄QQ何情况下Q程序结果都<strong>无法预知</strong>?br><br>        四?. 对omit_return_in_otherQ是E序员的错误?br><br><br> <hr width="80%"> <br>五?实践<br><br>不知道ؓ(f)什么C++标准在这里开一?#8220;后门”?br>——C++在许多地斚w是很<strong>严}</strong>的?br><br>在实际应用中Q尽量不要采用这一Ҏ(gu), 因ؓ(f)Q?br>1. 旧编译器不支?br>2. C不支持——如果希望main能同时按C语言~译的话<br><br>对于<strong>演示</strong>用的C++代码Q与主题无关的代码行能省则省Q则可以使用q一Ҏ(gu)?br>比如QC++标准中的CZ代码几乎都采用了q一Ҏ(gu)?br>由此可得出,C++标准在这里开后门的原因是——让C++标准更薄^_^<br><br> <hr width="90%"> <br>相关链接Q?br><br>——示例代?br><a >http://immature.googlecode.com/svn/trunk/iMmature/sample/omit_return_in_main<br><br></a> <hr width="90%"> <p><br><a rel=license><img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" alt="Creative Commons License" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png"></a><br>?span xmlns:dc="http://purl.org/dc/elements/1.1/" rel="dc:type">作品</span>采用<a rel=license>知识׃n|名-非商业性?相同方式׃n 2.5 中国大陆许可协议</a>q行许可?<br><br>转蝲h?Q?br>文章作?- OwnWaterloo<br>发表旉 - 2009q?4?6?br>原文链接 - <a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/26/omit_return_in_main.html">http://www.shnenglu.com/ownwaterloo/archive/2009/04/26/omit_return_in_main.html</a></p> <img src ="http://www.shnenglu.com/ownwaterloo/aggbug/81116.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/ownwaterloo/" target="_blank">OwnWaterloo</a> 2009-04-26 14:37 <a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/26/omit_return_in_main.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>可变长参数列表误Z陷阱——va_arg不可接受的类?/title><link>http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/unacceptable_type_in_va_arg.html</link><dc:creator>OwnWaterloo</dc:creator><author>OwnWaterloo</author><pubDate>Tue, 21 Apr 2009 15:41:00 GMT</pubDate><guid>http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/unacceptable_type_in_va_arg.html</guid><wfw:comment>http://www.shnenglu.com/ownwaterloo/comments/80655.html</wfw:comment><comments>http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/unacceptable_type_in_va_arg.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.shnenglu.com/ownwaterloo/comments/commentRss/80655.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/ownwaterloo/services/trackbacks/80655.html</trackback:ping><description><![CDATA[实现一个有可变长参数列表函数的时候,?x)用到stdarg.hQ这里不讨论varargs.hQ中提供的宏?br><br>例如Q我们要实现一个简易的my_printfQ?br>1. 它只q回voidQ?不记录输出的字符数目<br>2. 它只接受"%d"按整数输出?%c"按字W输出?%%"输出'%'本n<br>如下Q?br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080"> 1</span> <span style="COLOR: #000000">#include </span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">stdarg.h</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 2</span> <span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 3</span> <span style="COLOR: #000000"></span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> my_printf(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000"> fmt, ... )<br></span><span style="COLOR: #008080"> 4</span> <span style="COLOR: #000000">{<br></span><span style="COLOR: #008080"> 5</span> <span style="COLOR: #000000">    <span style="COLOR: #0000ff">va_list</span> ap;<br></span><span style="COLOR: #008080"> 6</span> <span style="COLOR: #000000">    <span style="COLOR: #ff00ff">va_start</span>(ap,fmt); </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> 用最后一个具有参数的cd的参数去初始化ap </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080"> 7</span> <span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000"> (;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">fmt;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">fmt)<br></span><span style="COLOR: #008080"> 8</span> <span style="COLOR: #000000">    {<br></span><span style="COLOR: #008080"> 9</span> <span style="COLOR: #000000">        </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> 如果不是控制字符 </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">10</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">fmt</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">11</span> <span style="COLOR: #000000">        {<br></span><span style="COLOR: #008080">12</span> <span style="COLOR: #000000">            putchar(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">fmt); </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> 直接输出 </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">13</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">continue</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">14</span> <span style="COLOR: #000000">        }<br></span><span style="COLOR: #008080">15</span> <span style="COLOR: #000000">        </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> 如果是控制字W,查看下一字符 </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">16</span> <span style="COLOR: #000000">        </span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">fmt;<br></span><span style="COLOR: #008080">17</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">\0</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">==*</span><span style="COLOR: #000000">fmt) </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> 如果是结束符 </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">18</span> <span style="COLOR: #000000">        {<br></span><span style="COLOR: #008080">19</span> <span style="COLOR: #000000">            assert(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);  </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> q是一个错?nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">20</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">21</span> <span style="COLOR: #000000">        }<br></span><span style="COLOR: #008080">22</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">switch</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">fmt)<br></span><span style="COLOR: #008080">23</span> <span style="COLOR: #000000">        {<br></span><span style="COLOR: #008080">24</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">: </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> q箋2?%'输出1?%' </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">25</span> <span style="COLOR: #000000">            putchar(</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">26</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">27</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">d</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">: </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> 按照int输出 </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">28</span> <span style="COLOR: #000000">            {<br></span><span style="COLOR: #008080">29</span> <span style="COLOR: #000000">                </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> 下一个参数是intQ取?nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">30</span> <span style="COLOR: #000000">                </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> i </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> <span style="COLOR: #ff00ff">va_arg</span>(ap,</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">31</span> <span style="COLOR: #000000">                printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%d</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,i);<br></span><span style="COLOR: #008080">32</span> <span style="COLOR: #000000">            }<br></span><span style="COLOR: #008080">33</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">34</span> <span style="COLOR: #000000">        </span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">c</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">: </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> 按照字符输出 </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">35</span> <span style="COLOR: #000000">            {<br></span><span style="COLOR: #008080">36</span> <span style="COLOR: #000000">                </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">* <span style="COLOR: #ff0000">但是Q下一个参数是char?/span></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">37</span> <span style="COLOR: #000000">                </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">  <span style="COLOR: #ff0000">可以q样取出?/span>Q?nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">38</span> <span style="COLOR: #000000">                </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> <span style="COLOR: #ff00ff">va_arg</span>(ap,</span><span style="COLOR: #ff0000"><strong>char</strong></span><span style="COLOR: #000000">);<br></span><span style="COLOR: #008080">39</span> <span style="COLOR: #000000">                printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%c</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,c);<br></span><span style="COLOR: #008080">40</span> <span style="COLOR: #000000">            }<br></span><span style="COLOR: #008080">41</span> <span style="COLOR: #000000">            </span><span style="COLOR: #0000ff">break</span><span style="COLOR: #000000">;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">43</span> <span style="COLOR: #000000">        }<br></span><span style="COLOR: #008080">44</span> <span style="COLOR: #000000">    }<br></span><span style="COLOR: #008080">45</span> <span style="COLOR: #000000">    <span style="COLOR: #ff00ff">va_end</span>(ap);  </span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> <strong style="COLOR: #ff0000">释放</strong>ap—?<strong><font color=#ff0000>必须Q?/font></strong> ?strong>相关链接</strong></span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">46</span> <span style="COLOR: #000000">}</span></div> <br><br>q与《C++E序设计语言》中的一道练?fn)题很类伹{?br>——需要支?%c"控制W?br><br>在《C++E序设计语言-题解》中Q给Z一个答案(中文p65)?br>但是Q?<strong>如同上面的代码一?/strong>Q它们都?strong style="COLOR: #ff0000">错误</strong>的!<br><br><br> <hr width="80%"> <br><br>单的_我们?span style="COLOR: #ff00ff">va_arg</span>(<span style="COLOR: #666699">ap</span>,<span style="COLOR: #0000ff">type</span>)取出一个参数的时候,<br><strong><span style="COLOR: #0000ff">type</span><span style="COLOR: #ff0000">l?/span>对不能ؓ(f)</strong>以下cdQ?br>—?span style="COLOR: #0000ff"><strong>char</strong></span>?span style="COLOR: #0000ff">signed</span> <span style="COLOR: #0000ff"><strong>char</strong></span>?span style="COLOR: #0000ff">unsigned</span> <span style="COLOR: #0000ff"><strong>char</strong></span><br>—?span style="COLOR: #0000ff"><strong>short</strong></span>?span style="COLOR: #0000ff">unsigned</span> <span style="COLOR: #0000ff"><strong>short</strong></span><br>—?span style="COLOR: #0000ff">signed</span> <span style="COLOR: #0000ff"><strong>short</strong></span>?span style="COLOR: #0000ff"><strong>short</strong></span> <span style="COLOR: #0000ff">int</span>?span style="COLOR: #0000ff">signed</span> <span style="COLOR: #0000ff"><strong>short</strong></span> <span style="COLOR: #0000ff">int</span>?span style="COLOR: #0000ff">unsigned</span> <span style="COLOR: #0000ff"><strong>short</strong></span> <span style="COLOR: #0000ff">int</span><br>—?span style="COLOR: #0000ff"><strong>float</strong></span><br><br><br>一个简单的理由是:(x)<br>—?strong>调用?span style="COLOR: #ff0000">l对?/span>?/strong>?span style="COLOR: #993300">my_printf</span><strong>传?/strong>以上cd?strong>实际参数</strong>?br><br><br>在C语言中,调用一个不带原型声明的函数Ӟ(x)<br>调用者会(x)?strong>每个</strong>参数执行“默认实际参数<strong>提升</strong>(default argument <strong>promotions</strong>)”?br><br>同时Q对可变长参数列?strong>出最后一?/strong>?strong>cd声明的Ş式参?/strong>之后?strong>每一个实际参?/strong>Q也执行上q提升工作?br>提升工作如下Q?br>——floatcd的实际参数将提升到double<br>——char、short和相应的signed、unsignedcd的实际参数提升到int<br>——如果int不能存储原|则提升到unsigned int<br><br>然后Q调用者将<strong>提升?/strong>的参?strong>传?/strong>l被调用者?br>所以,my_printf?strong>l对无法接收?/strong>上述cd的实际参数的?br><br><br> <hr width="80%"> <br>上面的代码的38?9行,应该改ؓ(f)Q?br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> c </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> <span style="COLOR: #ff00ff">va_arg</span>(ap,</span><span style="COLOR: #0000ff"><strong>int</strong></span><span style="COLOR: #000000">);<br>printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">%c</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,c);</span></div> <br>同理Q?如果需要用short和floatQ?也应该这P(x)<br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #0000ff">short</span><span style="COLOR: #000000"> s </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">short</span><span style="COLOR: #000000">)va_arg(ap,</span><span style="COLOR: #0000ff"><strong>int</strong></span><span style="COLOR: #000000">);<br></span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000"> f </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">)va_arg(ap,</span><span style="COLOR: #0000ff"><strong>double</strong></span><span style="COLOR: #000000">);</span></div> <br>q也是printf族函数没有用于short和float的控制符的原因?br><br> <hr width="90%"> <br>附录Q?br><br>在《C语言E序设计》对可变长参数列表的相关章节中,q没有提到这个陷阱?br>但是有提到默认实际参数提升的规则Q?br><br>在没有函数原型的情况下,char与shortcd都将被{换ؓ(f)intcdQfloatcd被转换为doublecd?br>                ——《C语言E序设计》第2? 2.7 cd转换 p36<br><br><br><br>在其他一些书c中Q也有提到这个规则:(x)<br><br><br>事情很清楚,如果一个参数没有声明,~译器就没有信息d它执行标准的cd查和转换?br>在这U情况下Q一个char或short作为int传递,float作为double传递?br>q些做未必是E序员所期望的?br>脚注Q这些都是由C语言l承来的标准提升?br>对于q略号表示的参敎ͼ其实际参数在传递之前L行这些提升(如果它们属于需要提升的cdQ,提升后的g递给有关的函数。——译者注<br>                ——《C++E序设计语言》第3?特别?7.6 p138<br><br>…… floatcd的参C(x)自动转换为doublecdQshort或charcd的参C(x)自动转换为intcd ……<br>                ——《C陷阱与缺陗?4.4 形参、实参与q回?p73<br><br><br>q里有一个陷阱需要避免:(x)<br>va_arg宏的W?个参C能被指定?strong>char</strong>?strong>short</strong>或?strong>float</strong>cd?br>因ؓ(f)char和shortcd的参C(x)被{换ؓ(f)intcdQ而floatcd的参C(x)被{换ؓ(f)doublecd ……<br>例如Q这样写<strong>肯定是不?/strong>的:(x)<br>c = va_arg(ap,char);<br>因ؓ(f)我们无法传递一个charcd参数Q如果传递了Q它?yu)?x)被自动{化ؓ(f)intcd。上面的式子应该写成Q?br>c = va_arg(ap,int);<br>                ——《C陷阱与缺陗p164<br><br> <hr width="90%"> <br>2009/05/07 修改Q?br>printf函数族有用于short的控制符“h”?br>见:(x)<a ><u><font color=#0000ff>http://www.cplusplus.com/reference/clibrary/cstdio/printf/</font></u></a><br><br> <hr width="90%"> <br>相关链接Q?br><br>——《可变长参数列表误区与陷阱——va_end是必ȝ吗??br><a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/is_va_end_necessary.html">http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/is_va_end_necessary.html</a><br><br> <hr width="90%"> <br><br><a rel=license><img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" alt="Creative Commons License" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png"></a><br><br>?span rel="dc:type" xmlns:dc="http://purl.org/dc/elements/1.1/">作品</span>采用<a rel=license>知识׃n|名-非商业性?相同方式׃n 2.5 中国大陆许可协议</a>q行许可?<br> <p>转蝲h?Q?br>文章作?- OwnWaterloo<br>发表旉 - 2009q?4?1?br>原文链接 - <a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/unacceptable_type_in_va_arg.html">http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/unacceptable_type_in_va_arg.html</a></p> <img src ="http://www.shnenglu.com/ownwaterloo/aggbug/80655.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/ownwaterloo/" target="_blank">OwnWaterloo</a> 2009-04-21 23:41 <a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/unacceptable_type_in_va_arg.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>可变长参数列表误Z陷阱——va_end是必ȝ吗?http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/is_va_end_necessary.htmlOwnWaterlooOwnWaterlooTue, 21 Apr 2009 07:53:00 GMThttp://www.shnenglu.com/ownwaterloo/archive/2009/04/21/is_va_end_necessary.htmlhttp://www.shnenglu.com/ownwaterloo/comments/80616.htmlhttp://www.shnenglu.com/ownwaterloo/archive/2009/04/21/is_va_end_necessary.html#Feedback2http://www.shnenglu.com/ownwaterloo/comments/commentRss/80616.htmlhttp://www.shnenglu.com/ownwaterloo/services/trackbacks/80616.htmlq本应是一个无M论的问题——当然必调用?br>
stdargQ或varargsQ下略)中提供的功能是一U?strong style="COLOR: red">契约Q?br>“你按我的U定方式使用q些?br>——即必须调用va_end
——我q你提供实现可变长参数列表所需要的功能?#8221;


使用stdarg本来?strong>?span style="COLOR: red">?/span>的事?br>—?strong>按照一个简单的契约Q另见相关链接)办事可以了
——根本无M解其具体实现?br>
有h乐意ȝI该功能是如何实现的Q?也很好?br>

可是某些?br>——或通过研究其的实现Q或通过实践
——发C所使用的^CQ?va_end是可以忽略的?br>之后Q他开始大攑֎?Q?“va_end是不必要的!”

由此Q?造成一些不必要的误解与争论?br>


让我们看看对va_end的两U态度Q?br>


一?va_end能省则省Q?br>
假设你用的某个C/C++~译器,提供的va_end是可忽略的?br>比如msvc中的va_end的实现如下:(x)
#define va_end(apap = (va_list)0  /* ap|空 */

通常直接使用va_start的函敎ͼ假设?strong>fQ的实现体会(x)很短。:(x)
1. ?span style="COLOR: #ff00ff">va_start初始?span style="COLOR: #0000ff">va_list
2. 调用一个?strong>va_list参数的函敎ͼ假设?strong>vfQ?br>Qvf 是一个固定参数列表的函数Q?br>
因ؓ(f)f的实C非常短, 一眼望Iѝ?br>所以你能确保vfq回后, ap不会(x)再被你用?br>
因此Q?ap|空除了费CPU周期Q?没有实际意义Q?是这样吗Q?br>

        一?.  ~译器参与优?br>
你能发现代码末尾ap不再被用, va_end其|空毫无意义?br>那么Q你的编译器能发现这个问题么Q?br>
h证一下?br>如果~译器也知道Q?q且没有为va_end生成M代码Q?那么省略va_end是不必要的了?br>
        一?. ~译器不参与优化

你编译器真ؓ(f)va_end生成了无意义q且令h感到无法接受的机器码Ӟ该怎么办?


                一?.1 你只在该~译器下工作

那么Q你省略va_end好了?br>但请不要宣扬一些带?strong>误导性质的言辞?br>当你?#8220;va_end是不需?#8221;的时候, 请附带说明:(x)
1. 你的q_
2. ?strong>?/span>考虑跨^?/strong>


                一?.2 需要要考虑UL到其他编译器

注意Q?其他~译器包括(但不限于Q:(x)
——不?strong>架构上的~译?br>——相同架构上的不?strong>~译器?/strong>
——相同架构上的相同编译器产品?strong>不同版本?br>
需要分析在该编译器下,对va_end的处理是?strong>依然可以被省?/strong>?br>——显Ӟq是一?strong>乏味的工作?br>

即你在源代码中写入 Q?/p>

/* va_end is trivial, omit it */

也难保它不会(x)?span style="COLOR: #ff0000">遗忘
—?UL一个程序的时候有太多工作要做?br>q么一个不L(fng)的地方, ?x)被惌v来么Q?br>

如果在被UL的编译器上:(x)
1. 省略va_end导致函C能正常返回(见附录)
也许立马p发现q个bug?br>崩掉了嘛Q?当然要引?#8220;重视”?br>
2. 省略va_end不会(x)立马崩溃Q?而是D内存泄露Q见附录Q?br>情况很严重了?br>E序依然q行“良好”?br>但是调用一ơ函敎ͼ 泄漏一点点内存?br>
q恐怕就要花很多旉才能查出来了?br>如果目旉再紧一点, 也许Ҏ(gu)来不及修复q个bug发布了?br>反正漏得?#8220;不多”Q?你说是吧Q?br>



二?va_end能留则留

我们何不换个方式Q?

1.  坚持使用va_end
——即便我们心里清楚它没做什么有用的事情也是如此?br>
代码UL本质是Q?不对q_QCPU、OS、Compiler{等Q?span style="COLOR: #ff0000">依赖?br>stdarg是标准库提供的一U实现可变长参数列表?strong style="COLOR: #ff0000">可移?/strong>方式?br>我们没理由弃之不用?br>
如果我们在源代码中坚持用va_endQ?br>——至在q点上,׃?strong>对编译器产生依赖Q?strong>省略va_endQ就是一U?span style="COLOR: #ff0000">依赖Q?br>——移植的时候, 自然无须为其操心?br>
2. va_end令编译器产生?strong>令h无法接受?strong style="COLOR: #ff0000">无用代码?br>——通常Q这是不?x)发生的?~译器厂商会(x)考虑q个事情?br>
比如上面的va_end宏, ?x)生一ơ不必要的赋值操作, 但通常?x)被~译器优化ؓ(f)I?br>即没有被优化ؓ(f)I, 一ơ赋值操作, 真的是不可容忍的么Q?br>
如果实不能容忍Q?作ؓ(f)一U?strong>Ҏ(gu)情ŞQ?可以q样 Q?/p>

#if defined(COMPILER1) || defined(COMPILER2|| ...
    
/*special situation
        the machine code generated by these compliers is unacceptable, omit it
    
*/
#else
    
/* general situation */
    va_end(ap);
#endif




附录 —?看看大牛们是怎么说的?br>
从一个用过va_start()的函C退Z前,必须调用一ơva_end()?br>q是因ؓ(f)va_start可能以某U方?strong>修改了堆?/strong>Q这U修改可能导?strong>q回无法完成Qva_end()能将有关的修改复原?br>                ——《C++E序设计语言?W?版、特别版Q?p139
——即上面提到?“立即崩溃”?br>

我们务必CQ在使用完va_list变量后一定要调用宏va_end?br>?strong>大多?/strong>C实现上,调用va_end?strong>否ƈ无区?/strong>?br>但是Q?strong>某些版本的va_start宏ؓ(f)了方便对va_list的遍历,q参数列表动态分配内?/strong>?br>q样一UC实现很可能利用va_end宏来释放此前动态分配的内存Q?br>如果忘记调用宏va_endQ最后得到的E序可能在某些机型上没有问题Q而在另一些机型上则发?#8220;内存泄露”?br>                ——《C陷阱与缺陗, p161
——即上面提到?#8220;内存泄露”?br>


…… 最后,必须在函数返回之?strong>调用
va_endQ以完成一些必要的清理工作?br>                ——《CE序设计语言?W?版, p137

……在所有参数处理完毕后Q?且在退出函数f之前Q?strong>必须调用宏va_end一?/strong> ……
                ——《CE序设计语言?W?版, p232

 



相关链接Q?


——可变长参数列表误区与陷阱——va_arg不可接受的类?br>http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/unacceptable_type_in_va_arg.html
q是使用stdarg提供的功能需要遵守契U之一?br>契约本n仍然是简单的?br>契约背后的原理也许比较晦涩, 但也可以不必兛_?br>



Creative Commons License
?span xmlns:dc="http://purl.org/dc/elements/1.1/" rel="dc:type">作品采用知识׃n|名-非商业性?相同方式׃n 2.5 中国大陆许可协议q行许可?

转蝲h?Q?br>文章作?- OwnWaterloo
发表旉 - 2009q?4?1?br>原文链接 - http://www.shnenglu.com/ownwaterloo/archive/2009/04/21/is_va_end_necessary.html

OwnWaterloo 2009-04-21 15:53 发表评论
]]>
~译器选项——语ahttp://www.shnenglu.com/ownwaterloo/archive/2009/04/20/compiler_options_language.htmlOwnWaterlooOwnWaterlooMon, 20 Apr 2009 07:02:00 GMThttp://www.shnenglu.com/ownwaterloo/archive/2009/04/20/compiler_options_language.htmlhttp://www.shnenglu.com/ownwaterloo/comments/80538.htmlhttp://www.shnenglu.com/ownwaterloo/archive/2009/04/20/compiler_options_language.html#Feedback0http://www.shnenglu.com/ownwaterloo/comments/commentRss/80538.htmlhttp://www.shnenglu.com/ownwaterloo/services/trackbacks/80538.html一?l一的预处理、编译、链接程?br>

        一?. 有些E序同时h如下功能Q?br>
1. 预处理C/C++源代?br>2. ~译C/C++源代?br>3. 链接C/C++目标代码

例如QGCC的gcc、g++QMSVC的cl.exe?br>

        一?. 实际的情况也许更加复杂:(x)

gcc、g++、cl.exe很有可能只是一?strong>启动?/strong>?br>用户只需要用它们, 它们内部再根?strong>特定条gQ?执行其他E序Q比如:(x)

1. gcc、g++~译C/C++代码Ӟ 最l会(x)执行cc1/cc1plusE序?br>该程序可能才是真正的C/C++~译器?br>
2. gcc、g++在链接C/C++目标代码Ӟ最l会(x)执行ldE序?br>该程序可能才是真正的链接器?br>
3. cl.exeE序自己处理C/C++代码的预处理与编译工作?br>
4. cl.exeE序链接Ӟ执?strong>link.exe?br>该程序可能才是真正的链接器?br>

        一?. 我们的关注点

——上q复杂的情况我们大多数情况下无须操心Q?br>
1. 我们只需要用gcc、g++
即以后GCCcc1、cc1plus、ld改ؓ(f)别的名字也不?x)受影响?br>
2. 我们只需要用cl
即以后cl不再担Q~译工作或者link.exe被改为别的名字,同样不受影响?br>

——我们需要关心这些统一的程序,?strong>Ҏ(gu)何种条gQ?军_它们的操作的Q?br>
本文只讨论编译:(x)
1. 它们默认是通过何种条gQ?军_按C语法或按C++语法~译一个翻译单元的?br>2. 如何昑ּ指定按C语法或者按C++语法ȝ译一个翻译单元?br>


二?默认情况

如果不显式指定操作, gcc、g++、cl都是按文件后~名来军_操作的?br>
        二?. 试文gQ?
#ifndef __cplusplus
/* being treated as C translation unit */
#error !---  C  ---!
#else
// being treated as C++ translation unit
#error !--- C++ ---!
#endif

我们Z个没有后~的文Ӟ叫nosuffixQ?写入如上内容?br>而且Q?我们也不需要编译出目标代码?br>只需要测试__cplusplus宏(见?a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html">预定义__cplusplus?/strong>》)是否存在Qƈ且用#error报告卛_?br>
然后建立一些内容完全一L(fng)文gQ?/p>

#include "nosuffix"


q些文g共有10个:(x)
c.c?cpp.cpp、txt.txt、UC.C、UCPP.CPP、cc.cc、cxx.cxx、inl.inl、c++.c++、cp.cp?br>QUC和UCPP是ؓ(f)了测试大写后~名)


        二?. 试Ҏ(gu)

对GCC使用Q?br>gcc(g++) filename >stdout.txt 2>stderr.txt

对MSVC使用Q?br>cl filename >stdout.txt 2>stderr.txt


        二?. 试l果

gcc、g++、cl对以下后~名文件的默认操作如下?/a>Q?br>

 

nosuffix

.c

.cpp

.txt

.C

.CPP

.cc

.cxx

.inl

.c++

.cp

gcc

obj

C

C++

obj

C++

C++

C++

C++

obj

C++

C++

g++

obj

C++

C++

obj

C++

C++

C++

C++

obj

C++

C++

cl

obj

C

C++

obj

C

C++

C++

C++

obj

obj

obj


对该表的几点说明Q?br>1. 表中的obj表示该条件下Q?l一E序它们认作目标文Ӟ q打执行链接工作?br>q显然是错误的, 因ؓ(f)他们包含的是文本?br>
2. gcc、g++Q编译代码)的区?br>GCC认ؓ(f)带有.c?cpp?C?CPP?cc?cxx?c++?cpQ但不限于)后缀的文件是C/C++源文件?br>gcc把带?c后缀的文Ӟ 当作C源文Ӟ 把带有其他后~名的文g当作C++源文件?br>g++带有上q所有后~的文Ӟ都当作C++源文件?br>
3. MSVC与GCC的区?br>MSVC认ؓ(f)带有.c?cpp?C?CPP?cc?cxx后缀的文件是C/C++源文件?br>上述GCC相比Q?排除?c++?cp

同时Qwindows下的文g名是不区分大写的, 所?c?CQ?cpp?CPP是一L(fng)?br>与GCC相比Q?.C不再认ؓ(f)是C++源文Ӟ 而是?c一样作为C源文件处理?br>

        二?. 试结

׃表以及说明, 如果我们打算~写跨^台的代码Q?br>
1. 不推荐用的后缀?br>.c++?cp
——因为它们不被MSVC支持
.C
——因为MSVCq不区别对待.c?C


2. 可以使用的后~?br>——对C源文?br>可以使用.c?br>
——对C++源文?br>可以使用.cpp?cc?cxx?br>
—?CPP不推?br>因ؓ(f)在xnix?a.CPP与a.cpp?个文Ӟ 而复制到Windows上就发生重名?br>如果只?cpp可以避免该情况?br>

3. 关于.inl
有些文g内容实是C/C++代码Q?但是却不直接作ؓ(f)译单元Q而是被其他翻译单元包含?br>理论上说Q它们取M名字都没关系。但是将它们取ؓ(f).inl?x)得C些好处:(x)
    —?nbsp; 暗示该文件包含C/C++代码
    —?nbsp; 一些编辑器?x)对其按C/C++语法q行高亮?br>




三?昑ּ指定

有时候需要覆盖默认情况,昑ּ指定我们需要的操作?br>
        三?. GCC “-x

GCC通过-x选项昑ּ指定~译源代码的语言Q?br>-x cQ或-xcQ?br>    —?nbsp; 源代码作ؓ(f)C源文件?br>-x c++、(?xc++Q?br>    —?nbsp; 源代码作ؓ(f)C++源文件?br>
对于“?#8221;中的试Q?只要命令行改ؓ(f)Q?br>gcc(g++) -x c (-xc) filename

所有文仉被作ؓ(f)C源文件处理, q输?error !---  C  ---!

而用如下命令行Q?br>gcc(g++) -x c++ (-xc++) filename

所有文仉被作ؓ(f)C++源文件处理, q输?error !--- C++ ---!


        三?. MSVC “/TC” “/TP”

MSVC通过/TCQ?TPQ选项Q?昑ּ指定输入作为CQC++Q源代码?br>
?#8220;?#8221;中的试Q?命o行:(x)
cl /TC filename

Ҏ(gu)有文仉输?error !---  C  --- !

 

命o行:(x)
cl /TP filename

Ҏ(gu)有文仉输?error !--- C++ ---!






四、ȝ

1. 使用“二?”中推荐的方式Q给源代码文件命名?br>2. 覆盖默认情况Q?x(GCC)或?TC?TPQMSVCQ?br>3. 带提一点, gcc、g++用作链接Ӟ 也有一些区别?br>链接C++Q或者C/C++混合Q目标代码, 推荐使用g++?br>因ؓ(f)GCC高版本中Q?gcc链接旉认不?x)导入C++需要的q行时库?br>




相关链接Q?br>
——源代码
http://immature.googlecode.com/svn/trunk/iMmature/sample/compiler_options/language

——?a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html">预定义__cplusplus?/a>?br>http://www.shnenglu.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html




Creative Commons License
?span xmlns:dc="http://purl.org/dc/elements/1.1/" rel="dc:type">作品采用知识׃n|名-非商业性?相同方式׃n 2.5 中国大陆许可协议q行许可?

转蝲h?Q?br>文章作?- OwnWaterloo
发表旉 - 2009q?4?0?br>原文链接 - http://www.shnenglu.com/ownwaterloo/archive/2009/04/20/compiler_options_language.html



OwnWaterloo 2009-04-20 15:02 发表评论
]]>
预定义__cplusplus?/title><link>http://www.shnenglu.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html</link><dc:creator>OwnWaterloo</dc:creator><author>OwnWaterloo</author><pubDate>Mon, 20 Apr 2009 06:42:00 GMT</pubDate><guid>http://www.shnenglu.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html</guid><wfw:comment>http://www.shnenglu.com/ownwaterloo/comments/80537.html</wfw:comment><comments>http://www.shnenglu.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/ownwaterloo/comments/commentRss/80537.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/ownwaterloo/services/trackbacks/80537.html</trackback:ping><description><![CDATA[<p>一?介绍预定义宏"__cplusplus"<br><br>        一.1 __cplusplus宏在C++标准中的描述如下Q?br><br>16.8 Predefined macro names<br>__cplusplus The name __cplusplus is defined to the value <strong style="COLOR: red">199711L</strong> when compiling a C++ translation unit.143)<br>143) It is <strong>intended</strong> that future versions of this standard will replace the value of this macro with a greater value.<br>Non-conforming compilers should use a value with <strong>at most five decimal digits</strong>.<br><br>                                        —?ISO C++03 p315<br>                                        —?ISO C++98 p309<br><br>如果一D代码是需要针对C++~写的, 可以使用该宏q行条g~译?br><br><br>        一.2 __cplusplus的值是<strong>Z</strong>表示C++的版?br>        一.3 __cplusplus的类型是"long int"<br><br><br>——这是理Z的?br>现在发布的C++标准只有C++98Q?C++03是C++98?strong>修订</strong>Q?内容只有很少改变?br>所以在ISO C++03中, 也规定该宏的值是199711LQ这是一?strong>长整数字面?/strong>Q?br><br>——实际上Q?目前<strong>不应?span style="COLOR: red">依赖</span>?/strong>宏的| 因ؓ(f)Q?br>1. 目前标准中规定的值只有一个—?99711LQ?没有Ҏ(gu)该D行条件编译的可能?br><br>2. 目前C++~译器ƈ不一?strong>按标准实?/strong>q个宏(见测试)?br><br> <hr width="80%"> <br>二?试预定义宏__cplusplus<br><br>CZ1Q? <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">#include </span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main() {<br><br></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> TO_LITERAL(text) TO_LITERAL_(text)</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000"> TO_LITERAL_(text) #text</span><span style="COLOR: #000000"><br>#ifndef __cplusplus<br></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> this translation unit is being treated as a C one </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>    printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">a C program\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br></span><span style="COLOR: #0000ff">#else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> this translation unit is being treated as a C++ one</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">    printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">a C++ program\n__cplusplus expands to \</span><span style="COLOR: #000000">""<br></span><span style="COLOR: #000000">          TO_LITERAL(__cplusplus) </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">\</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br>    (</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)getchar();<br>    </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>}<br></span></div> <p>代码很简单:(x)<br>如果没有定义__cplusplusQ?那么当前源代码被当作C源代码处理?br>如果定义了__cplusplusQ那么当前源代码被当中C++源代码处理, q且输出__cplusplus宏被展开后的字符丌Ӏ?br><br><br>CZ2Q?/p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">__cplusplus</span></div> <p>q段代码更简单了Q?只是使用了__cplusplus宏?br>然后查看预处理(见?a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/get_result_of_preprocessing.html"><strong>查看源文仉处理l果</strong></a>》)Q看其被扩展后的l果?br><br> <hr width="80%"> <br>三?试l果<br><br>        ——msvc8<br>        ——msvc9<br>__cplusplus按照标准被扩展ؓ(f)—?99711L?br><br>        ——msvc6<br>        ——gcc (GCC) 3.4.2 (mingw-special)<br>        ——gcc (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu3)<br>__cplusplus只是单的被扩展ؓ(f)—??br><br><br>q也说明了不应该依赖__cplusplus宏的倹{?br><br> <hr width="90%"> <br>相关链接Q?br><br>——源代码<br><a >http://immature.googlecode.com/svn/trunk/iMmature/sample/predefined_macro/__cplusplus</a><br><br>——?a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/get_result_of_preprocessing.html">查看源文仉处理l果</a>?br><a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/get_result_of_preprocessing.html">http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/get_result_of_preprocessing.html</a><br><br> <hr width="90%"> <br><a rel=license><img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" alt="Creative Commons License" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png"></a><br>?span xmlns:dc="http://purl.org/dc/elements/1.1/" rel="dc:type">作品</span>采用<a rel=license>知识׃n|名-非商业性?相同方式׃n 2.5 中国大陆许可协议</a>q行许可?<br><br>转蝲h?Q?br>文章作?- OwnWaterloo<br>发表旉 - 2009q?4?0?br>原文链接 - <a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html">http://www.shnenglu.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html</a> <img src ="http://www.shnenglu.com/ownwaterloo/aggbug/80537.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/ownwaterloo/" target="_blank">OwnWaterloo</a> 2009-04-20 14:42 <a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>预定义__GNUC__?/title><link>http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/predefined_macro___GNUC__.html</link><dc:creator>OwnWaterloo</dc:creator><author>OwnWaterloo</author><pubDate>Thu, 16 Apr 2009 12:07:00 GMT</pubDate><guid>http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/predefined_macro___GNUC__.html</guid><wfw:comment>http://www.shnenglu.com/ownwaterloo/comments/80178.html</wfw:comment><comments>http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/predefined_macro___GNUC__.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/ownwaterloo/comments/commentRss/80178.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/ownwaterloo/services/trackbacks/80178.html</trackback:ping><description><![CDATA[<p>一?介绍预定义宏“__GNUC__”<br><br>        一.1 __GNUC__ 是gcc~译器编译代码时预定义的一个宏?br><br>需要针对gcc~写代码Ӟ 可以使用该宏q行条g~译?br><br>        一.2 __GNUC__ 的DCgcc的版本?br><br>需要针对gcc特定版本~写代码Ӟ也可以用该宏进行条件编译?br><br>        一.3 __GNUC__ 的类型是“int”<br><br>该宏被扩展后Q?得到的是<strong>整数字面?/strong>?br>可以通过<strong>仅预处理</strong>Q查看宏扩展后的<strong>文本</strong>。见Q?strong><a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/get_result_of_preprocessing.html#__GNUC__"><strong>查看源文仉处理l果</strong></a></strong>?br>同时下面的示例也能体现出q一炏V?br><br> <hr width="80%"> <br>二?试预定义宏__GNUC__<br><br>CZQ? <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">#include </span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">assert.h</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"><br>#include </span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">stdio.h</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"><br>#include </span><span style="COLOR: #000000"><</span><span style="COLOR: #000000">typeinfo</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"><br><br>#ifndef __GNUC__<br></span><span style="COLOR: #0000ff">#error</span><span style="COLOR: #000000"> sample for gcc compiler</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">#else</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008000">/*</span><span style="COLOR: #008000"> use gcc special extension: #warning , __attribute__, etc.  </span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">#endif</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000"> main() {<br>    printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">hello gcc %d\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,__GNUC__);<br>    assert( typeid(__GNUC__)</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">typeid(</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">) );<br>    printf(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">press Enter to exit\n</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>    (</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)getchar();<br>}<br></span></div> <p><br> <hr width="90%"> <br>修改Q?br><br>—?009/04/18<br><br>__GNUC__<br>__GNUC_MINOR__<br>__GNUC_PATCHLEVEL__<br>These macros are defined by all GNU compilers that use the C preprocessor:<br>C, C++, and Objective-C. Their values are the major version, minor version,<br>and patch level of the compiler, as <strong><span style="COLOR: red">integer</span> constants</strong>. For example, GCC 3.2.1<br>will define __GNUC__ to 3, __GNUC_MINOR__ to 2, and __GNUC_PATCHLEVEL__ to<br>1. They are defined only when the entire compiler is in use; if you invoke the<br>preprocessor directly, they are not defined.<br><br>      —?<a ><u><font color=#0000ff>http://gcc.gnu.org/onlinedocs/gcc-3.1.1/cpp/Common-Predefined-Macros.html#Common%20Predefined%20Macros</font></u></a><br> <hr width="90%"> <br>相关链接Q?br><br>——源代码<br><a >http://immature.googlecode.com/svn/trunk/iMmature/sample/predefined_macro/extension/__GNUC__/</a><br><br>——《查看源文g预处理结果?br><a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/get_result_of_preprocessing.html">http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/get_result_of_preprocessing.html</a><br><br>——《预定义_MSC_VER宏?br><a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/15/predefined_macro__MSC_VER.html">http://www.shnenglu.com/ownwaterloo/archive/2009/04/15/predefined_macro__MSC_VER.html</a><br><br><br> <hr width="90%"> <br>  <a rel=license><img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" alt="Creative Commons License" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png"></a><br>?span xmlns:dc="http://purl.org/dc/elements/1.1/" rel="dc:type">作品</span>采用<a rel=license>知识׃n|名-非商业性?相同方式׃n 2.5 中国大陆许可协议</a>q行许可?<br><br>转蝲h?Q?br>文章作?- OwnWaterloo<br>发表旉 - 2009q?4?6?br>原文链接 - <a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/predefined_macro___GNUC__.html">http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/predefined_macro___GNUC__.html</a> <img src ="http://www.shnenglu.com/ownwaterloo/aggbug/80178.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/ownwaterloo/" target="_blank">OwnWaterloo</a> 2009-04-16 20:07 <a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/predefined_macro___GNUC__.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>配置msvc命o行环?l?——编写msvc~译脚本http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/write_compile_script_for_msvc.htmlOwnWaterlooOwnWaterlooWed, 15 Apr 2009 19:42:00 GMThttp://www.shnenglu.com/ownwaterloo/archive/2009/04/16/write_compile_script_for_msvc.htmlhttp://www.shnenglu.com/ownwaterloo/comments/80101.htmlhttp://www.shnenglu.com/ownwaterloo/archive/2009/04/16/write_compile_script_for_msvc.html#Feedback0http://www.shnenglu.com/ownwaterloo/comments/commentRss/80101.htmlhttp://www.shnenglu.com/ownwaterloo/services/trackbacks/80101.html阅读全文

OwnWaterloo 2009-04-16 03:42 发表评论
]]>
查看源文仉处理l果http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/get_result_of_preprocessing.htmlOwnWaterlooOwnWaterlooWed, 15 Apr 2009 16:49:00 GMThttp://www.shnenglu.com/ownwaterloo/archive/2009/04/16/get_result_of_preprocessing.htmlhttp://www.shnenglu.com/ownwaterloo/comments/80093.htmlhttp://www.shnenglu.com/ownwaterloo/archive/2009/04/16/get_result_of_preprocessing.html#Feedback4http://www.shnenglu.com/ownwaterloo/comments/commentRss/80093.htmlhttp://www.shnenglu.com/ownwaterloo/services/trackbacks/80093.html~译C/C++源代码时Q源代码首先?x)被预处理器QpreprocessorQ进行预处理QpreprocessQ?br>预处理器执行源代码中?strong>预处理指?/strong>Q如Q?br>——文件包?br>#include
——条件编?br>#if?#ifdef?#ifndef?#elif?#else?#endif
——宏
#define?#undef、宏标识W、宏扩展
——其?br>#error?line?pragma
……

预处理之后的l果Q即提交给~译器)与程序员看到的源代码也许?x)?strong>很大的差?/strong>?br>其在源代码中含有许多错l复杂的宏与条g~译时?br>当我们被q些狂ؕ的宏与条件编译折的时候, 如果能看到预处理的结果, 也许?x)有很大的帮助?br>
下面以一个示例说明msvc与gcc中得到预处理l果的方式?br>


零?CZ

假设我们需要查?_MSC_VER ?nbsp;__GUNC__ 两个宏最l被扩展出的文本Q?nbsp;
int main() {
    
int result = 
#if defined(__GNUC__)
__GNUC__
#elif defined(_MSC_VER)
_MSC_VER
#else
#error unknown compiler
#endif
;
    
return result;
}

该程序很单, main函数q回一个resultQ然后立即退出?br>而result的| Ҏ(gu)条g~译得到Q?br>1. 如果是GCC~译器, 那么result赋gؓ(f)__GNUC__
2. 否则如果是VC~译器, 那么result赋gؓ(f)_MSC_VER
3. 否则是一个未知的~译器, 错误

接下来, 我们来看看_MSC_VER与__GNUC__q?个宏最l到底被扩展Z么文本?br>



一?GCC

        一.1?-E 选项

-E选项把预处理的l果Q写入stdout?br>也就是说Q?执行如下命oQ?br>gcc -E preporcess_only.c

p在控制台中得到预处理后的l果Q大致如下:(x)
# 1 "../preprocess_only.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "../preprocess_only.c"
int main() {
    int result =

3





;
    return result;
}


可以看到Q?__GUNC__ 宏最l被扩展为整数字面量3QGCC 3Q?br>
如果源代码很长, 输出到命令行H口中查看也怸方便?br>如何其输出C个文件中呢?


                一.1.1?重定?br>
因ؓ(f)-E是输出到stdoutQ?昄可以其重定向到另一个文Ӟ 如执行如下命令:(x)
gcc -E preprocess_only.c >stdout.txt

那么stdout.txt中, p得到刚才命o行窗口中的内宏V?br>

                一.1.2?-o Q小写) 选项

-o选项用于指定出文件名?br>对于-cQ?-o指定的是目标文g名?br>对于-S Q?o指定的是汇编文g名?br>对于-EQ?-o自然也可以指定预处理文g名, 如执行如下命令:(x)
gcc -E preprocess_only.c -o output.txt

那么output.txt中会(x)得到“一.1.1”中的stdout.txt?#8220;一.1”中控制台H口一L(fng)l果?br>

        一.2?save-temps 选项

-save-temps选项保?strong>中间文gQ如预处理后的结果文件、汇~代码文件与目标文g?br>其中的预处理l果文gQ通常?strong>.i后缀Q是我们所需要的?br>

举例Q?br>1?gcc -save-temps -E preprocess_only.c
0个中间文件?br>输出预处理结果, ?#8220;一.1”一P 输出到控制台H口中?br>Ҏ(gu)如下命oQ?br>
1.1?nbsp;gcc -save-temps -E preprocess_only.c -o temp_output.txt
1.2?gcc -save-temps -E preprocess_only.c >temp_output.txt
可以看出Q?-E选项不生中间文件?预处理结果就是最l结果?br>同时可以使用 -o选项或者重定向Q?把结果保存到一个文件中?br>

2?gcc -save-temps -S preprocess_only.c
1个中间文Ӟ(x) preprocess_only.iQ预处理l果Q?br>1个输出文Ӟ(x)preprocess_only.sQ汇~代码)
Ҏ(gu)如下命oQ?br>
2.1?gcc -save-temps -S preprocess_only.c -o unknown
得到preprocess_only.i文gQ内Ҏ(gu)预处理结果,是中间文件?br>得到unknown文gQ内Ҏ(gu)汇编代码Q?是最l结果文件?br>

3?gcc -save-temps -c preprocess_only.c
2个中间文Ӟ(x) preprocess_only.i与preprocess_only.s?br>1个输出文Ӟ(x) preprocess_only.oQ目标代码)
Ҏ(gu)如下命oQ?br>
3.1?gcc -save-temps -c preprocess_only.c -o unknown
得到preprocess_only.i ?preprocess_only.s文gQ内容分别是预处理结果与汇编代码Q是中间l果?br>unknown文gQ?内容是目标代码,是最l结果文件?br>
4?gcc -save-temps preprocess_only.c
3个中间文Ӟ(x) preprocess_only.i、preprocess_only.s、preprocess_only.o?br>1个输出文Ӟ(x) a.outQa.exe with mingwQ?br>Ҏ(gu)如下命oQ?br>
4.1?gcc -save-temps preprocess_only.c -o what
得到上述3个文Ӟ 是中间文件?br>what文gQwhat.exe with mingwQ, 内容是可执行代码Q?是最l结果文件?br>




二?MSVC

VC6??中与查看预处理相关的选项可以通过如下命o查看Q?br>cl /help

在输ZQ?nbsp;?-PREPROCESSOR- q个cd?br>其中与预处理l果相关的有如下一些选项Q?br>
        ?1?E 选项

/E preprocess to stdout
/E 预处理定向?stdout

昄Q?q和“一.1”是等L(fng)Q?如:(x)
cl /E preprocess_only.c

在命令行H口中将得到cMl果Q?
#line 1 "preprocess_only.c"
int main() {
    int result = 


#line 6 "preprocess_only.c"
1200


#line 10 "preprocess_only.c"
;
    return result;
}

可以看到Q?_MSC_VER宏最l被扩展为整数字面?200QVC6Q?br>
对于较长的源文gQ?我们同样希望结果输出到一个文件中?br>

                ?1.1、重定向

执行Q?br>cl /E preprocess_only.c >stdout.txt

stdout.txt保存上面的l果?br>
注意Q?在msvc中,没有“一.1.2”的对应物?br>执行Q?br>cl /help

在输Z扑ֈ-OUTPUT FILES-cdQ?可以看到没有命名预处理结果的方式。有两个怼的选项Q?br>/Fe 命名可执行文件?br>/Fp 命名预编译头文g?br>但不是我们需要的选项?br>

也许VC认ؓ(f)通过 “/E + 重定?#8221;可以达到命名输出文件的目的?br>所以就没有设计辑ֈ此目的的另一U方法?br>

        ?2?P 选项

/P preprocess to file
/P 预处理到文g

执行Q?br>cl /P preprocess_only.c

得?preprocess_only.i

/P?x)将?nbsp;xxx.suffix 的预处理l果输出?xxx.i 文g中?br>没有指定文g名的方式?如果需?strong>指定输出文g?/strong>Q?可以使用 “/E + 重定?#8221;


        ?3 /EP 选项

/E?P选项都将保留一部分Q源文gQ行信息Q如“?1”所C?br>如果q是不需要的Q?可以使用 /EP选项?br>
/EP preprocess to stdout, no #line
/EP 预处理到标准输出Q没?#line

如:(x)
cl /EP preprocess_only.c

得到如下输出:(x)

int main() {
    
int result = 



1200



;
    
return result;
}


同样Q?如果需要输出到指定文gQ?可以使用重定?/strong>?br>

        ?4 其他一些有的选项

1. /C Q大写)
don't strip commentsQ不抽出注释Q?br>如果保留注释对理解预处理l果有帮助, 可以使用q个选项?br>
2. /U /u
/u remove all predefined macros
/u U除所有预定义的宏

/U<name> remove predefined macro
/U<name> U除预定义的?br>
比如可以通过Q?br>cl /u preprocess_only.c
cl /U_MSC_VER preprocess_only.c

来得C?unknown complier错误?#8230;…


3. /D
/D<name>{=|#}<text> define macro
/D<name>{=|#}<text> 定义?br>
可以通过Q?br>cl /D__GUNC__=3 preprocess_only.c

来假装gcc~译器囧……



 


相关链接Q?br>
——示例文件下?br>http://immature.googlecode.com/svn/trunk/iMmature/sample/compiler_options/preprocess_only/
http://www.shnenglu.com/Files/ownwaterloo/preprocess_only.zip

——《配|msvc命o行环境?br>http://www.shnenglu.com/ownwaterloo/archive/2009/04/15/environment_for_using_cl_from_command_line.html

——《配|msvc命o行环?l?——编写msvc~译脚本?br>http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/write_compile_script_for_msvc.html

——《预定义_MSC_VER宏?br>http://www.shnenglu.com/ownwaterloo/archive/2009/04/15/predefined_macro__MSC_VER.html

——《预定义__GNUC__宏?br>http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/predefined_macro___GNUC__.html
 


 

 
Creative Commons License
?span xmlns:dc="http://purl.org/dc/elements/1.1/" rel="dc:type">作品采用知识׃n|名-非商业性?相同方式׃n 2.5 中国大陆许可协议q行许可?

转蝲h?Q?br>文章作?- OwnWaterloo
发表旉 - 2009q?4?6?br>原文链接 - http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/preprocess_only.html



OwnWaterloo 2009-04-16 00:49 发表评论
]]>
配置msvc命o行环?/title><link>http://www.shnenglu.com/ownwaterloo/archive/2009/04/15/environment_for_using_cl_from_command_line.html</link><dc:creator>OwnWaterloo</dc:creator><author>OwnWaterloo</author><pubDate>Wed, 15 Apr 2009 13:29:00 GMT</pubDate><guid>http://www.shnenglu.com/ownwaterloo/archive/2009/04/15/environment_for_using_cl_from_command_line.html</guid><wfw:comment>http://www.shnenglu.com/ownwaterloo/comments/80059.html</wfw:comment><comments>http://www.shnenglu.com/ownwaterloo/archive/2009/04/15/environment_for_using_cl_from_command_line.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/ownwaterloo/comments/commentRss/80059.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/ownwaterloo/services/trackbacks/80059.html</trackback:ping><description><![CDATA[<p>有些时候用命令行而不是IDEȝ译源代码?x)比较方ѝ?br>而在命o行下使用msvc的编译器——clQ?需要ؓ(f)光|?strong>环境</strong>?br><br> <hr width="80%"> <br>一?环境变量试<br><br>试cl的环境是否配|妥当, 可以执行如下试Q?br>win?R 启动q行 -> 输入cmdQwinntpdQ或者commandQwin95pdQ?-> 回RQ?打开命o行窗口?br>键入"cl"q回车, 如果有类似如下的输出 Q?br><br>--------------------------------------------------------------------------------<br>Microsoft (R) 32-bit C/C++ Optimizing Compiler Version <strong>12</strong>.00.8168 for 80x86<br>Copyright (C) Microsoft Corp 1984-1998. All rights reserved. <br><br>usage: cl [ option... ] filename... [ /link linkoption... ]<br>--------------------------------------------------------------------------------<br>Microsoft (R) 32-bit C/C++ Optimizing Compiler Version <strong>14</strong>.00.50727.42 for 80x86<br>Copyright (C) Microsoft Corporation.  All rights reserved.<br><br>usage: cl [ option... ] filename... [ /link linkoption... ]<br>--------------------------------------------------------------------------------<br>用于 80x86 ?Microsoft (R) 32 ?C/C++ 优化~译?<strong>15</strong>.00.30729.01 ?br>版权所?C) Microsoft Corporation。保留所有权利?br><br>用法: cl [ 选项... ] 文g?.. [ /link 链接选项... ] <p>--------------------------------------------------------------------------------<br><br>一般来_ 可以在命o行下使用cl了?br><br>cl文g版本与VS版本、VC产品版本、_MSC_VER宏的对应关系如下<a id=VS_VC_CL_MSC_VER_TABLE>?/a>Q?/p> <p> <table style="WIDTH: 480px; BORDER-COLLAPSE: collapse; HEIGHT: 126px" cellSpacing=0 cellPadding=3 border=1> <tbody> <tr> <td> <p align=center>VS版本</p> </td> <td> <p align=center>VC产品版本?/p> </td> <td> <p align=center>cl文g版本?/p> </td> <td> <p align=center>_MSC_VER宏的?/p> </td> </tr> <tr> <td> <p align=center>98</p> </td> <td> <p align=center>6.x</p> </td> <td> <p align=center>12.x</p> </td> <td> <p align=center>1200</p> </td> </tr> <tr> <td> <p align=center>2005</p> </td> <td> <p align=center>8.x</p> </td> <td> <p align=center>14.x</p> </td> <td> <p align=center>1400</p> </td> </tr> <tr> <td> <p align=center>2008</p> </td> <td> <p align=center>9.x</p> </td> <td> <p align=center>15.x</p> </td> <td> <p align=center>1500</p> </td> </tr> </tbody> </table> </p> <p><br> <hr width="80%"> <br>二?试p|<br><br>如果出现Q?br>1. “cl不是内部或外部命令,也不是可q行的程序或批处理文件?#8221;<br>说明cl不在Path环境变量中?br><br>2. 找不到xxx.dll?br>cl在Path环境变量中, Path中缺必要的dll的\径?br><br>3. 上述试通过Q?但是在编译时出现找不到头文g或者库?br>说明Path环境变量中有cl和必要dll的\径, 但是仍缺其他一些环境变量?br><br>q些情况Q?都需要进一步配|环境变量?br><br> <hr width="80%"> <br>三?配置环境变量<br><br>        ?1 、让安装包帮助注册环境变?br><br>VC6在安装的时候,?x)弹Z个对话框Q让你选择是否注册VC6的环境变量。如下:(x)<br><br>For your convenince, the environment variables required to run build tools from a command prompt are saved in the VCVARS32.BAT in your BIN directory<br><br>Q复选框Q?nbsp;<strong>Register Environment Variables<br></strong><br>Turn on this option to register environment variables for running Visual C++ tools from the command line.<br><br>默认复选框是没有选中的?br>如果选中Q?安装完毕后就?x)添加必要的环境变量?br><br><br>所以, 一个办法是重新安装VC6Q反正很,相对于VC8?安装十分快速)?br><br><br>        ?2 ?a id=vc6env>手工d环境变量</a><br><br>以VC6举例Q我们可以在 Q?#8220;我的?sh)?#8221; -> “属?#8221; -> “高” -> “环境变量”中添加如下变量:(x)<br><br>%Path%="<strong><em>prefix</em></strong>\Microsoft Visual Studio\VC98\Bin";%Path%<br>cl.exe所在\径?br><br>%include%="<strong><em>prefix</em></strong>\Microsoft Visual Studio\VC98\Include";%include%<br>%lib%="<strong><em>prefix</em></strong>\Microsoft Visual Studio\VC98\Lib";%lib%<br>C/C++以及Platform SDK<br><br>%include%="<strong><em>prefix</em></strong>\Microsoft Visual Studio\VC98\MFC\Include";%include%   <br>%lib%="<strong><em>prefix</em></strong>\Microsoft Visual Studio\VC98\MFC\Lib";%include%<br>MFC<br><br>%include%="<strong><em>prefix</em></strong>\Microsoft Visual Studio\VC98\ATL\Include";%include%<br>ATL<br><br>Q其中的<strong><em>prefix</em></strong>是安装目录的前缀Q之后就可以在命令行中用cl了?br><br><br>同时Q?VC6??都提供了一个批处理<strong>vcvars32.bat</strong>?br>我们可以查看相应的vcvars32.bat最l做了什么工作,而手工加入需要的变量?br>下内Ҏ(gu)自我机器上的v<strong style="COLOR: red">s</strong>vars32.batQVC8?的vcvars32.bat最l调用它们)Q?br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Code_Closed_Image_225038 onclick="this.style.display='none'; Code_Closed_Text_225038.style.display='none'; Code_Open_Image_225038.style.display='inline'; Code_Open_Text_225038.style.display='inline';" height=16 src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" width=11 align=top><img id=Code_Open_Image_225038 style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_225038.style.display='none'; Code_Closed_Image_225038.style.display='inline'; Code_Closed_Text_225038.style.display='inline';" height=16 src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width=11 align=top><span id=Code_Closed_Text_225038 style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">vc8</span><span id=Code_Open_Text_225038 style="DISPLAY: none"><br><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">@set PATH</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\Common7\IDE;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\VC\BIN;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\Common7\Tools;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\Common7\Tools\bin;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\VC\PlatformSDK\bin;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\SDK\v2.</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">\bin;C:\WINDOWS\Microsoft.NET\Framework\v2.</span><span style="COLOR: #000000">0.50727</span><span style="COLOR: #000000">;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\VC\VCPackages;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">PATH</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000"><br>@set INCLUDE</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\VC\ATLMFC\INCLUDE;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\VC\INCLUDE;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\VC\PlatformSDK\include;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\SDK\v2.</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">\include;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">INCLUDE</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000"><br>@set LIB</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\VC\ATLMFC\LIB;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\VC\LIB;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\VC\PlatformSDK\lib;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\SDK\v2.</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">\lib;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">LIB</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000"><br>@set LIBPATH</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">C:\WINDOWS\Microsoft.NET\Framework\v2.</span><span style="COLOR: #000000">0.50727</span><span style="COLOR: #000000">;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">\VC\ATLMFC\LIB</span></span></div> <br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Code_Closed_Image_225000 onclick="this.style.display='none'; Code_Closed_Text_225000.style.display='none'; Code_Open_Image_225000.style.display='inline'; Code_Open_Text_225000.style.display='inline';" height=16 src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" width=11 align=top><img id=Code_Open_Image_225000 style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_225000.style.display='none'; Code_Closed_Image_225000.style.display='inline'; Code_Closed_Text_225000.style.display='inline';" height=16 src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width=11 align=top><span id=Code_Closed_Text_225000 style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">vc9</span><span id=Code_Open_Text_225000 style="DISPLAY: none"><br><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #000000">@set PATH</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">9.0</span><span style="COLOR: #000000">\Common7\IDE;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">9.0</span><span style="COLOR: #000000">\VC\BIN;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">9.0</span><span style="COLOR: #000000">\Common7\Tools;C:\WINDOWS\Microsoft.NET\Framework\v3.</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">;C:\WINDOWS\Microsoft.NET\Framework\v2.</span><span style="COLOR: #000000">0.50727</span><span style="COLOR: #000000">;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">9.0</span><span style="COLOR: #000000">\VC\VCPackages;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">PATH</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000"><br>@set INCLUDE</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">9.0</span><span style="COLOR: #000000">\VC\ATLMFC\INCLUDE;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">9.0</span><span style="COLOR: #000000">\VC\INCLUDE;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">INCLUDE</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000"><br>@set LIB</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">9.0</span><span style="COLOR: #000000">\VC\ATLMFC\LIB;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">9.0</span><span style="COLOR: #000000">\VC\LIB;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">LIB</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000"><br>@set LIBPATH</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">C:\WINDOWS\Microsoft.NET\Framework\v3.</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">;C:\WINDOWS\Microsoft.NET\Framework\v2.</span><span style="COLOR: #000000">0.50727</span><span style="COLOR: #000000">;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">9.0</span><span style="COLOR: #000000">\VC\ATLMFC\LIB;D:\Program Files\Microsoft Visual Studio </span><span style="COLOR: #000000">9.0</span><span style="COLOR: #000000">\VC\LIB;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">LIBPATH</span><span style="COLOR: #000000">%</span></span></div> <br>可以Ҏ(gu)它们Q给VC8?讄环境变量?br><br><br>      ?3 、用vcvars32.bat<br><br>上面提到vcvars32.batQ它们的位置如下Q?br><br>VC6  <em><strong>prefix</strong></em>\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT<br>VC8  <strong><em>prefix</em></strong>\Microsoft Visual Studio 8\VC\bin\vcvars32.bat<br>VC9  <strong><em>prefix</em></strong>\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat<br><br>需要注意的是:(x) q些批处理文件只?x)?strong>当前q程</strong>中设|(局部的Q环境变量,也就是说Q?br><br>1. 用cmdQ或者commandQ打开的命令行H口中, q行某个vcvar32.bat一ơ?br>那么当前命o行窗口中可以正怋用clQ直到关闭?br><br>2. 写批处理文g需要?strong style="COLOR: red">call</strong> <strong><em>prefix</em></strong>\vcvars32.batQ而不是直接启动vcvars32.bat?br>前者ؓ(f)当前q程Qcpl.bat创徏的进E)d局部于q程环境变量?br>后者启动一个进E, 为其加入环境变量Q?然后该进E立即退出——没有Q何作用?br><br><br>      ?4?使用VSXXCOMNTOOLS变量QVC8?Q?br><br>对于VC8?有另一U方式——不注册全局的(pȝ或当前用P环境变量Q仅为当前进E设|(局部的Q环境变量?br>因ؓ(f)VC8?都可?strong>很方?/strong>的ؓ(f)单个q程讄环境变量?br><br>观察vc8和vc9的vcvars32.bat的内容(位置见上Q, 发现它们都只有一行:(x)<br>"%V<span style="COLOR: red">S</span>80COMNTOOLS%v<span style="COLOR: red">s</span>vars32.bat"<br>"%V<span style="COLOR: red">S</span>90COMNTOOLS%v<span style="COLOR: red">s</span>vars32.bat"<br><br>VS80COMNTOOLS、VS90COMNTOOLSQ注意不是VC而是VSQ分别是VS2005和VS2008安装后会(x)讄的环境变量?br>所以我们也可以在自q批处理中Q很方便的ؓ(f)当前q程讄需要的环境变量。如下:(x)<br><br>call "<strong>%VS80COMNTOOLS%</strong>vsvars32.bat"<br>以下cl命o执行VC8的cl?br><br>call "<strong>%VS90COMNTOOLS%</strong>vsvars32.bat"<br>以下cl命o执行VC9的cl?br><br> <hr width="80%"> <br>四?ȝ<br><br>如果仅需要用某个版本的VCQ?q且只ؓ(f)自己方便而用命令行Q?可以使用上面M一U方式?br>单归U_下:(x)<br><br>1?使用全局环境变量——在pȝ或当前用户变量中加入需要的倹{?br>        1.1 重新安装<br>        1.2 手工加入<br><br>2?不用全局环境变量<br>——在执行cl前,先用对应的vcvars32.batQ命令行H口中执行或者脚本中call prefix\vcvars32.batQ?br><br>        2.1 vcvars32.bat加入Path变量<br>        2.2 使用"%V<span style="COLOR: red">S</span><strong>XX</strong>COMNTOOLS%v<strong style="COLOR: red">s</strong>vars.bat" (VC8?Q?或?absolutePath\vcvars32.bat<br><br><br>如果需要用多个版本的VC?或者需要将~译脚本发布l客户用, ׃能这么随意了?br>具体见:(x)?a class=titlelink id=Editor_Results_rprSelectionList_ctl01_LinkTitle href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/write_compile_script_for_msvc.html"><font color=#000000><strong>配置msvc命o行环?l?——编写msvc~译脚本</strong></font></a>?br><br> <p> <hr width="80%"> <br>相关链接Q?br><br>——?a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/write_compile_script_for_msvc.html"><font color=#000000><strong>配置msvc命o行环?l?——编写msvc~译脚本</strong></font></a>?br><a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/write_compile_script_for_msvc.html">http://www.shnenglu.com/ownwaterloo/archive/2009/04/16/write_compile_script_for_msvc.html</a> <p><br>——?a ><strong>IDE 不是E序员的唯一选择Q一Q?/strong></a>?br><a >http://blog.codingnow.com/2008/09/replacement_of_ide_1.html</a><br><br> <hr width="90%"> <br> <br><a rel=license><img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" alt="Creative Commons License" src="http://i.creativecommons.org/l/by-nc-sa/2.5/cn/88x31.png"></a><br>?span rel="dc:type" xmlns:dc="http://purl.org/dc/elements/1.1/">作品</span>采用<a rel=license>知识׃n|名-非商业性?相同方式׃n 2.5 中国大陆许可协议</a>q行许可?br><br>转蝲h?Q?br>文章作?- OwnWaterloo<br>发表旉 - 2009q?4?5?br>原文链接 - <a id=Editor_Edit_hlEntryLink title="view: 配置msvc命o行环? href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/15/environment_for_using_cl_from_command_line.html" target=_blank>http://www.shnenglu.com/ownwaterloo/archive/2009/04/15/environment_for_using_cl_from_command_line.html</a> <img src ="http://www.shnenglu.com/ownwaterloo/aggbug/80059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/ownwaterloo/" target="_blank">OwnWaterloo</a> 2009-04-15 21:29 <a href="http://www.shnenglu.com/ownwaterloo/archive/2009/04/15/environment_for_using_cl_from_command_line.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.zl6688.com.cn" target="_blank">޹뾫ƷŮ˾þþò </a>| <a href="http://www.dripnews.cn" target="_blank">˾ƷþѶ</a>| <a href="http://www.ahlmnet.cn" target="_blank">޾Ʒþþ</a>| <a href="http://www.jzxqbz.cn" target="_blank">һƷþð͹</a>| <a href="http://www.97hh.cn" target="_blank">Ʒþþþþ</a>| <a href="http://www.sidongliiang.cn" target="_blank">ŷƷþþþþþο</a>| <a href="http://www.robuts.com.cn" target="_blank">þþþþþòҰ¸߳</a>| <a href="http://www.hjj9588.cn" target="_blank">þ޾Ʒһ</a>| <a href="http://www.8910wan.cn" target="_blank">91Ʒ91Ⱦþþþø</a>| <a href="http://www.hyattzhuzhou.cn" target="_blank">99þþùƷ޿</a>| <a href="http://www.ru87.cn" target="_blank">þۺϸϾþù </a>| <a href="http://www.3gdd.cn" target="_blank">wwwԾþþcom</a>| <a href="http://www.3secshop.cn" target="_blank">99þۺϾƷ</a>| <a href="http://www.huameizc.cn" target="_blank">ҹƷþþþ </a>| <a href="http://www.mothersenvogue.com.cn" target="_blank">þþƷ޾Ʒɫ </a>| <a href="http://www.montblanc-fola.cn" target="_blank">պþëƬ</a>| <a href="http://www.gods2.cn" target="_blank">ɫվþav</a>| <a href="http://www.sh-bz.com.cn" target="_blank">˾þô߽</a>| <a href="http://www.vz82.cn" target="_blank">ݺۺϾþۺ88</a>| <a href="http://www.fotoblog.cn" target="_blank">þþžѾƷ6</a>| <a href="http://www.damangdao.cn" target="_blank">þ޾ƷĻ</a>| <a href="http://www.leshuapay.com.cn" target="_blank">þùѾƷ</a>| <a href="http://www.y447.cn" target="_blank">ҹþӰԺ</a>| <a href="http://www.yxcyfa.cn" target="_blank">þþþùƷ۲ӰԺ</a>| <a href="http://www.ruea.cn" target="_blank">vaþþþ</a>| <a href="http://www.cqqianmei.cn" target="_blank">պ޾Ʒþ</a>| <a href="http://www.shjinhuashiye.cn" target="_blank">2021þùԲľƷ</a>| <a href="http://www.5qzone.cn" target="_blank">޾Ʒþ</a>| <a href="http://www.ktv025.cn" target="_blank">߾þþƷĹ</a>| <a href="http://www.itewei.cn" target="_blank">97þۺɫdžѿ</a>| <a href="http://www.xbbu.cn" target="_blank">þѾƷav </a>| <a href="http://www.guer.org.cn" target="_blank">þþþavӰ</a>| <a href="http://www.lbyk.com.cn" target="_blank">þۺһ</a>| <a href="http://www.lefanz.cn" target="_blank">AVþþþò</a>| <a href="http://www.novagroup.com.cn" target="_blank">þ99ۺϾƷ</a>| <a href="http://www.hxjxjt88.cn" target="_blank">97Ʒ97þþþþ</a>| <a href="http://www.siteni.cn" target="_blank">ҹƷþþþþ˳</a>| <a href="http://www.gebendongxi.cn" target="_blank">ɫþþۺ</a>| <a href="http://www.waygoing.com.cn" target="_blank">2021þþƷ</a>| <a href="http://www.hybtw.cn" target="_blank">þþþav</a>| <a href="http://www.sh-yd.com.cn" target="_blank">󽶾þĻ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>