﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-hwliu11</title><link>http://www.cppblog.com/hwliu11/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 07 Apr 2026 14:02:19 GMT</lastBuildDate><pubDate>Tue, 07 Apr 2026 14:02:19 GMT</pubDate><ttl>60</ttl><item><title>GFORTRAN 64位openmp问题</title><link>http://www.cppblog.com/hwliu11/archive/2017/02/04/214646.html</link><dc:creator>隔壁老刘</dc:creator><author>隔壁老刘</author><pubDate>Sat, 04 Feb 2017 02:59:00 GMT</pubDate><guid>http://www.cppblog.com/hwliu11/archive/2017/02/04/214646.html</guid><wfw:comment>http://www.cppblog.com/hwliu11/comments/214646.html</wfw:comment><comments>http://www.cppblog.com/hwliu11/archive/2017/02/04/214646.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hwliu11/comments/commentRss/214646.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hwliu11/services/trackbacks/214646.html</trackback:ping><description><![CDATA[GFORTRAN在64位时候设置线程数目使用OMP_SET_NUM_THREADS无法生效，查看glibc代码，可以看出OMP_SET_NUM_THREADS是用C语言实现的，fortran参数传过来默认为地址，而OMP_SET_NUM_THREADS把传过来地址默认处理为32位地址，所以调用失败，64位下要使用专门处理64位地址的对应函数OMP_SET_NUM_THREADS_8_，上述两个函数输入参数不需要确认输入的integer是32位还是64位，这个与Intel Fortran不一样，Intel Fortran只是需要确认OMP_SET_NUM_THREADS的参数是32位还是64位<img src ="http://www.cppblog.com/hwliu11/aggbug/214646.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hwliu11/" target="_blank">隔壁老刘</a> 2017-02-04 10:59 <a href="http://www.cppblog.com/hwliu11/archive/2017/02/04/214646.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/C++位运算的陷阱</title><link>http://www.cppblog.com/hwliu11/archive/2016/04/12/213239.html</link><dc:creator>隔壁老刘</dc:creator><author>隔壁老刘</author><pubDate>Tue, 12 Apr 2016 02:41:00 GMT</pubDate><guid>http://www.cppblog.com/hwliu11/archive/2016/04/12/213239.html</guid><wfw:comment>http://www.cppblog.com/hwliu11/comments/213239.html</wfw:comment><comments>http://www.cppblog.com/hwliu11/archive/2016/04/12/213239.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/hwliu11/comments/commentRss/213239.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hwliu11/services/trackbacks/213239.html</trackback:ping><description><![CDATA[昨天用C/C++写Base64编码，结果老是不对，<br />比如<br /><div><span style="white-space:pre">			</span>unsigned char A =;</div><div><span style="white-space:pre">			</span>unsigned char B = ;</div><div><span style="white-space:pre">			</span>unsigned char C = ;<br />unsigned char a, b, c, d;<span style="white-space:pre">	<br /></span><div>a = A &gt;&gt; 2;<br /><div>b=(A &lt;&lt; 6) &gt;&gt; 2|(B&gt;&gt;4);<br /><div>c = ((B &lt;&lt; 4)) &gt;&gt; 2) | (C &gt;&gt; 6);<br /><div>d = (C &lt;&lt; 2) &gt;&gt; 2;<br />结果发现bcd值都不对<br />但是写成<br /><div>b = A&lt;&lt; 6;<br /><div>b = b &gt;&gt; 2;<br />b=b|B&gt;&gt;4;<br />就可以，查看b计算两种方式汇编<br />第一种<br /><div>00BACB66 &nbsp;movzx &nbsp; &nbsp; &nbsp; eax,byte ptr [ebp-1F9h] &nbsp;</div><div>00BACB6D &nbsp;shl &nbsp; &nbsp; &nbsp; &nbsp; eax,6 &nbsp;</div><div>00BACB70 &nbsp;sar &nbsp; &nbsp; &nbsp; &nbsp; eax,2 &nbsp;</div><div>00BACB73 &nbsp;mov &nbsp; &nbsp; &nbsp; &nbsp; byte ptr [ebp-1C9h],al &nbsp;</div><div>第二种</div><div>00BACB79 &nbsp;movzx &nbsp; &nbsp; &nbsp; eax,byte ptr [ebp-1F9h] &nbsp;</div><div>00BACB80 &nbsp;shl &nbsp; &nbsp; &nbsp; &nbsp; eax,6 &nbsp;</div><div>00BACB83 &nbsp;mov &nbsp; &nbsp; &nbsp; &nbsp; byte ptr [ebp-1EDh],al &nbsp;</div><div>00BACB89 &nbsp;movzx &nbsp; &nbsp; &nbsp; eax,byte ptr [ebp-1EDh] &nbsp;</div><div>00BACB90 &nbsp;sar &nbsp; &nbsp; &nbsp; &nbsp; eax,2 &nbsp;</div><div>00BACB93 &nbsp;mov &nbsp; &nbsp; &nbsp; &nbsp; byte ptr [ebp-1EDh],al &nbsp;<br />问题就在指令sar，这是算数右移位指令，会保留最高位，而第二种可以是因为movzx &nbsp;将高位已经置零<br />找到了原因，可以写为<br /><div><span style="white-space:pre">		</span>a = A &gt;&gt; 2;</div><div><span style="white-space:pre">		</span>b=((unsigned char)(A &lt;&lt; 6)) &gt;&gt; 2|(B&gt;&gt;4);</div><div><span style="white-space:pre">		</span>c = (((unsigned char)(B &lt;&lt; 4)) &gt;&gt; 2) | (C &gt;&gt; 6);</div><div><span style="white-space:pre">		</span>d = ((unsigned char)(C &lt;&lt; 2)) &gt;&gt; 2;<br />只要涉及到右移，保证操作数是无符号就可以了。</div></div></div></div></div></div></div></div></div><img src ="http://www.cppblog.com/hwliu11/aggbug/213239.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hwliu11/" target="_blank">隔壁老刘</a> 2016-04-12 10:41 <a href="http://www.cppblog.com/hwliu11/archive/2016/04/12/213239.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Intel OpenMP运行时错误 OMP: Error #133 解决办法</title><link>http://www.cppblog.com/hwliu11/archive/2016/02/27/212897.html</link><dc:creator>隔壁老刘</dc:creator><author>隔壁老刘</author><pubDate>Sat, 27 Feb 2016 04:13:00 GMT</pubDate><guid>http://www.cppblog.com/hwliu11/archive/2016/02/27/212897.html</guid><wfw:comment>http://www.cppblog.com/hwliu11/comments/212897.html</wfw:comment><comments>http://www.cppblog.com/hwliu11/archive/2016/02/27/212897.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hwliu11/comments/commentRss/212897.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hwliu11/services/trackbacks/212897.html</trackback:ping><description><![CDATA[<span style="font-size: 12px;">OMP: Error #133: Inconsistent THREADPRIVATE common block declarations are non-conforming and are unsupported. Either all threadprivate common blocks must be declared identically, or the largest instance of each threadprivate common block must be referenced first during the run.<br /><br />发生以上错误确实很麻烦，而且可参考文档基本没有。Fortran代码中的Common块数据大小可以不一样大（相同名称的Common），但是在OpenMP中确要求，要么大小一样，要么占用内存最大的先调用，变量如果是隐式声明，一定要注意，变量名称不同，可能会编译为不同长度的内存</span><img src ="http://www.cppblog.com/hwliu11/aggbug/212897.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hwliu11/" target="_blank">隔壁老刘</a> 2016-02-27 12:13 <a href="http://www.cppblog.com/hwliu11/archive/2016/02/27/212897.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenCASCADE 6.9.1 Bug</title><link>http://www.cppblog.com/hwliu11/archive/2015/11/12/212253.html</link><dc:creator>隔壁老刘</dc:creator><author>隔壁老刘</author><pubDate>Thu, 12 Nov 2015 07:20:00 GMT</pubDate><guid>http://www.cppblog.com/hwliu11/archive/2015/11/12/212253.html</guid><wfw:comment>http://www.cppblog.com/hwliu11/comments/212253.html</wfw:comment><comments>http://www.cppblog.com/hwliu11/archive/2015/11/12/212253.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hwliu11/comments/commentRss/212253.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hwliu11/services/trackbacks/212253.html</trackback:ping><description><![CDATA[<div><div>OpenCASCADE 6.9.1（估计从6.9.0开始），使用新的屏幕选择算法，我使用6.8开发的程序，升级到6.9.1之后，使用IVTK部分模型无法选中几何元素，经过调试发现6.9.1代码有BUG，导致数据丢失，无法判断选中的元素是否在选择范围，BUG出现的文件为SelectMgr_RectangularFrustum.cxx中的函数ScaleAndTransform<br /><div>NCollection_Handle&lt;SelectMgr_BaseFrustum&gt; SelectMgr_RectangularFrustum::ScaleAndTransform (const Standard_Integer theScaleFactor,<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const gp_Trsf&amp; theTrsf)<br /> {<br /> &nbsp; Standard_ASSERT_RAISE (theScaleFactor &gt; 0,<br /> &nbsp;&nbsp;&nbsp; "Error! Pixel tolerance for selection should be greater than zero");</div><div></div><div>&nbsp; SelectMgr_RectangularFrustum* aRes = new SelectMgr_RectangularFrustum();<br /> &nbsp; const Standard_Boolean isToScale = theScaleFactor != 1;<br /> &nbsp; const Standard_Boolean isToTrsf&nbsp; = theTrsf.Form() != gp_Identity;</div><div></div><div>&nbsp; if (!isToScale &amp;&amp; !isToTrsf)<br /> return aRes ;//这里，当部分模型满足该条件，返回一个空的数据，使用该数据无法判断模型是否在区域</div><div></div><div></div><div>&nbsp; aRes-&gt;myIsOrthographic = myIsOrthographic;<br /> &nbsp; SelectMgr_RectangularFrustum* aRef = this;</div><div></div><div>&nbsp; if (isToScale)<br /> &nbsp; {<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myNearPickedPnt = myNearPickedPnt;<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myFarPickedPnt&nbsp; = myFarPickedPnt;<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myViewRayDir&nbsp;&nbsp;&nbsp; = myViewRayDir;</div><div></div><div>&nbsp;&nbsp;&nbsp; const gp_Pnt2d aMinPnt (myMousePos.X() - theScaleFactor * 0.5,<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myMousePos.Y() - theScaleFactor * 0.5);<br /> &nbsp;&nbsp;&nbsp; const gp_Pnt2d aMaxPnt (myMousePos.X() + theScaleFactor * 0.5,<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; myMousePos.Y() + theScaleFactor * 0.5);</div><div></div><div>&nbsp;&nbsp;&nbsp; // recompute base frustum characteristics from scratch<br /> &nbsp;&nbsp;&nbsp; computeFrustum (aMinPnt, aMaxPnt, myBuilder, aRes-&gt;myVertices, aRes-&gt;myEdgeDirs);</div><div></div><div>&nbsp;&nbsp;&nbsp; aRef = aRes;<br /> &nbsp; }</div><div></div><div>&nbsp; if (isToTrsf)<br /> &nbsp; {<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myNearPickedPnt = aRef-&gt;myNearPickedPnt.Transformed (theTrsf);<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myFarPickedPnt&nbsp; = aRef-&gt;myFarPickedPnt.Transformed (theTrsf);<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myViewRayDir&nbsp;&nbsp;&nbsp; = aRes-&gt;myFarPickedPnt.XYZ() - aRes-&gt;myNearPickedPnt.XYZ();</div><div></div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // LeftTopNear<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myVertices[0] = aRef-&gt;myVertices[0].Transformed (theTrsf);<br /> &nbsp;&nbsp;&nbsp; // LeftTopFar<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myVertices[1] = aRef-&gt;myVertices[1].Transformed (theTrsf);<br /> &nbsp;&nbsp;&nbsp; // LeftBottomNear<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myVertices[2] = aRef-&gt;myVertices[2].Transformed (theTrsf);<br /> &nbsp;&nbsp;&nbsp; // LeftBottomFar<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myVertices[3] = aRef-&gt;myVertices[3].Transformed (theTrsf);<br /> &nbsp;&nbsp;&nbsp; // RightTopNear<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myVertices[4] = aRef-&gt;myVertices[4].Transformed (theTrsf);<br /> &nbsp;&nbsp;&nbsp; // RightTopFar<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myVertices[5] = aRef-&gt;myVertices[5].Transformed (theTrsf);<br /> &nbsp;&nbsp;&nbsp; // RightBottomNear<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myVertices[6] = aRef-&gt;myVertices[6].Transformed (theTrsf);<br /> &nbsp;&nbsp;&nbsp; // RightBottomFar<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myVertices[7] = aRef-&gt;myVertices[7].Transformed (theTrsf);</div><div></div><div>&nbsp;&nbsp;&nbsp; // Horizontal<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myEdgeDirs[0] = aRes-&gt;myVertices[4].XYZ() - aRes-&gt;myVertices[0].XYZ();<br /> &nbsp;&nbsp;&nbsp; // Vertical<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myEdgeDirs[1] = aRes-&gt;myVertices[2].XYZ() - aRes-&gt;myVertices[0].XYZ();<br /> &nbsp;&nbsp;&nbsp; // LeftLower<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myEdgeDirs[2] = aRes-&gt;myVertices[2].XYZ() - aRes-&gt;myVertices[3].XYZ();<br /> &nbsp;&nbsp;&nbsp; // RightLower<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myEdgeDirs[3] = aRes-&gt;myVertices[6].XYZ() - aRes-&gt;myVertices[7].XYZ();<br /> &nbsp;&nbsp;&nbsp; // LeftUpper<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myEdgeDirs[4] = aRes-&gt;myVertices[0].XYZ() - aRes-&gt;myVertices[1].XYZ();<br /> &nbsp;&nbsp;&nbsp; // RightUpper<br /> &nbsp;&nbsp;&nbsp; aRes-&gt;myEdgeDirs[5] = aRes-&gt;myVertices[4].XYZ() - aRes-&gt;myVertices[5].XYZ();<br /> &nbsp; }</div><div></div><div>&nbsp; // compute frustum normals<br /> &nbsp; computeNormals (aRes-&gt;myEdgeDirs, aRes-&gt;myPlanes);</div><div></div><div>&nbsp; cacheVertexProjections (aRes);</div><div></div><div>&nbsp; return NCollection_Handle&lt;SelectMgr_BaseFrustum&gt; (aRes);<br /> }</div></div>修改办法： <br /><div>&nbsp; if (!isToScale &amp;&amp; !isToTrsf)<br />&nbsp; {<br />&nbsp;&nbsp; aRes-&gt;myPixelTolerance=myPixelTolerance; <br />&nbsp;&nbsp; aRes-&gt;myIsOrthographic=myIsOrthographic;</div><div></div><div>&nbsp;&nbsp; aRes-&gt;myBuilder= myBuilder;</div><div></div><div>&nbsp;&nbsp; aRes-&gt;myIsOrthographic = myIsOrthographic;<br />&nbsp;&nbsp; aRes-&gt;myNearPickedPnt = myNearPickedPnt;<br />&nbsp;&nbsp; aRes-&gt;myFarPickedPnt = myFarPickedPnt;<br />&nbsp;&nbsp; aRes-&gt;myViewRayDir = myViewRayDir;<br />&nbsp;&nbsp; aRes-&gt;myMousePos = myMousePos;<br />&nbsp;&nbsp; <br />&nbsp;&nbsp; for (int i = 0; i &lt;6;++i)<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; aRes-&gt;myPlanes[i] = myPlanes[i];<br />&nbsp;&nbsp; }<br />&nbsp;&nbsp; for (int i = 0; i &lt; 6; ++i)<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; aRes-&gt;myVertices[i] = myVertices[i];<br />&nbsp;&nbsp; }<br />&nbsp;&nbsp; for (int i = 0; i &lt; 6; ++i)<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; aRes-&gt;myMaxVertsProjections[i] = myMaxVertsProjections[i];<br />&nbsp;&nbsp; }<br />&nbsp;&nbsp; for (int i = 0; i &lt; 6; ++i)<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; aRes-&gt;myMinVertsProjections[i] = myMinVertsProjections[i];<br />&nbsp;&nbsp; }<br />&nbsp;&nbsp; for (int i = 0; i &lt;3; ++i)<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; aRes-&gt;myMaxOrthoVertsProjections[i] = myMaxOrthoVertsProjections[i];<br />&nbsp;&nbsp; }<br />&nbsp;&nbsp; for (int i = 0; i &lt;3; ++i)<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; aRes-&gt;myMinOrthoVertsProjections[i] = myMinOrthoVertsProjections[i];<br />&nbsp;&nbsp; }<br />&nbsp;&nbsp; for (int i = 0; i &lt; 6; ++i)<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp; aRes-&gt;myEdgeDirs[i] = myEdgeDirs[i];<br />&nbsp;&nbsp; }<br />&nbsp;&nbsp; return NCollection_Handle&lt;SelectMgr_BaseFrustum&gt;(aRes);<br />&nbsp; }</div></div><strong></strong><img src ="http://www.cppblog.com/hwliu11/aggbug/212253.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hwliu11/" target="_blank">隔壁老刘</a> 2015-11-12 15:20 <a href="http://www.cppblog.com/hwliu11/archive/2015/11/12/212253.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++智能指针类用不好害死人</title><link>http://www.cppblog.com/hwliu11/archive/2015/11/07/212213.html</link><dc:creator>隔壁老刘</dc:creator><author>隔壁老刘</author><pubDate>Sat, 07 Nov 2015 13:43:00 GMT</pubDate><guid>http://www.cppblog.com/hwliu11/archive/2015/11/07/212213.html</guid><wfw:comment>http://www.cppblog.com/hwliu11/comments/212213.html</wfw:comment><comments>http://www.cppblog.com/hwliu11/archive/2015/11/07/212213.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/hwliu11/comments/commentRss/212213.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/hwliu11/services/trackbacks/212213.html</trackback:ping><description><![CDATA[<div>C++智能指针类使用起来方便，但是不维护好引用计数，不能随时控制对象的释放，反而造成内存耗尽，这样说来，反而不能随时控制对象的生命周期，所以使用要谨慎啊。</div><img src ="http://www.cppblog.com/hwliu11/aggbug/212213.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/hwliu11/" target="_blank">隔壁老刘</a> 2015-11-07 21:43 <a href="http://www.cppblog.com/hwliu11/archive/2015/11/07/212213.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>