这个问题实际上是不久前在programming.reddit.com 上进行有趣讨论的结果.它基本归结为以下代码:
int foo(int bar)
{
int return_value = 0;
if (!do_something( bar )) {
goto error_1;
}
if (!init_stuff( bar )) {
goto error_2;
}
if (!prepare_stuff( bar )) {
goto error_3;
}
return_value = do_the_thing( bar );
error_3:
cleanup_3();
error_2:
cleanup_2();
error_1:
cleanup_1();
return return_value;
}
Run Code Online (Sandbox Code Playgroud)
goto这里的使用似乎是最好的方法,导致所有可能性中最干净,最有效的代码,或者至少在我看来.在Code Complete中引用Steve McConnell :
goto在分配资源,对这些资源执行操作,然后释放资源的例程中很有用.使用goto,您可以清理代码的一部分.goto可以降低忘记在检测到错误的每个位置释放资源的可能性.
此方法的另一个支持来自本节中的" Linux设备驱动程序"一书.
你怎么看?这种情况goto在C中是否有效?您是否更喜欢其他方法,这些方法会产生更复杂和/或效率更低的代码,但是要避免goto?
我最近实现线程/互斥管理器的努力最终导致75%的CPU负载(4核心),而所有四个正在运行的线程都处于睡眠状态或等待互斥锁解锁.
具体的类太大了,不能完全发布在这里,但我可以把原因缩小到两个互斥锁的死锁安全获取
std::unique_lock<std::mutex> lock1( mutex1, std::defer_lock );
std::unique_lock<std::mutex> lock2( mutex2, std::defer_lock );
std::lock( lock1, lock2 );
Run Code Online (Sandbox Code Playgroud)
该类的另一部分使用std::condition_variablewith wait()和notify_one()on mutex1来同时有选择地执行某些代码.
简单的改变
std::unique_lock<std::mutex> lock1( mutex1 );
std::unique_lock<std::mutex> lock2( mutex2 );
Run Code Online (Sandbox Code Playgroud)
使CPU使用率降至正常的1-2%.
我不敢相信,std::lock()功能是低效的.这可能是g ++ 4.6.3中的错误吗?
编辑:(示例)
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
std::mutex mutex1, mutex2;
std::condition_variable cond_var;
bool cond = false;
std::atomic<bool>done{false};
using namespace std::chrono_literals;
void Take_Locks()
{
while( !done )
{
std::this_thread::sleep_for( 1s );
std::unique_lock<std::mutex> lock1( mutex1, std::defer_lock …Run Code Online (Sandbox Code Playgroud) 我刚刚意识到阅读这个页面,std :: shared_ptr的构造函数与单个指针参数不是noexcept.
因此,以下代码包含可能的内存泄漏:
std::shared_ptr<int> p3 (new int);
Run Code Online (Sandbox Code Playgroud)
原因是可能发生两次分配:
这里有两个问题:
如果第二个分配抛出异常,第一个分配的内存泄漏,这是真的吗?
如果答案是肯定的:
使用std :: shared_ptr的正确习惯用法是什么?
我正在使用Visual Studio,我非常喜欢轨道更改功能:
过了一会儿,我正在编辑的文件完全是绿色的.当它发生时,我想清除所有的标记.
我找到了三种方法,但它们并不像我想的那么简单:
关闭并重新打开Visual Studio.
关闭并重新打开所有文件.
打开选项对话框,取消选中该功能,重新打开对话框并重新检查功能.

有一条神奇的捷径吗?
许多CPU具有用于返回单个组件的操作码的高 32位的整数乘法的序位.通常将两个32位整数相乘会产生64位结果,但如果将其存储为32位整数,则会将其截断为低32位.
例如,在PowerPC上,mulhw操作码在一个时钟内返回32位32位乘法的64位结果的高32位.这正是我正在寻找的,但更便携.在NVidia CUDA中有一个类似的操作码,umulhi().
在C/C++中,是否有一种有效的方法来返回32x32乘法的高阶位?目前我通过转换为64位来计算它,例如:
unsigned int umulhi32(unsigned int x, unsigned int y)
{
unsigned long long xx=x;
xx*=y;
return (unsigned int)(xx>>32);
}
Run Code Online (Sandbox Code Playgroud)
但这比常规的32乘32乘以慢11倍,因为即使是乘法,我也使用了过度的64位数学运算.
有更快的方法来计算高阶位吗?
对于BigInteger库来说,这显然不是最好的解决方案(这是一种过度杀伤并且会产生巨大的开销).
SSE似乎有PMULHUW,16x16 - > 16位版本,但不是32x32 - > 32版本,就像我在寻找.
我已经尝试了几天用Visual Studio 2013构建静态版本的Qt.我只是无法弄清楚我做错了什么.
系统:
我多次做了什么:
对于每个文件夹,我启动了Visual Studio x86命令行并运行:
对于我试过的-static vs -shared或Qt 5.2.1 vs Qt 5.3.0 alpha的每个变体,这总是成功的.
在Qt Creator中
我可以注册各种套件,使用共享Qt库编译和启动任何示例.另一方面,使用静态Qt库的示例从未编译过.该错误始终如下所示:LNK1104:无法打开文件'C:/Qt/5.3.0/msvc2013-static/lib/translator_common.lib'.问题是文件丢失(调试模式下的translator_commond.lib或发布模式下的translator_common.lib)
在Visual Studio 2013中(使用Visual Studio Addin 1.2.3 alpha)
我可以添加Qt版本并更改我的解决方案的Qt版本.如果可以使用共享版本的Qt编译并运行一个非常简单的程序:
#include <QtCore> …Run Code Online (Sandbox Code Playgroud) 看完这个问题后.我创建了这个小小的测试:
class A{
public:
A(){}
A(const A&){printf("copy\n");}
A(A&&){printf("move\n");}
static A f(){
A a;
return a;}
static A g(){
A a;
return (a);}//could be return *&a; too.
static A h(){
A a;
return true?a:a;}
};
Run Code Online (Sandbox Code Playgroud)
结果是(没有RVO和NRVO):
据我所知,用于决定是否使用复制或移动的规则在12.8.32中描述:
这是指12.8.31的规则:(我只显示相关部分)
按照这些规则,我理解f和h会发生什么:
怎么样?
对我来说,它看起来很像h.我正在返回一个表达式,它不是自动对象的名称,因此我认为它会被复制但是它被移动了.这里发生了什么?
我很难找到一种可靠的方法来获取Windows上的硬件线程数量.我在具有双CPU Intel Xeon E5-2699 v3 @ 2.30GHz的计算机上运行Windows 7 Professional SP1 64位,共计36个内核和72个线程.我已经尝试了不同的方法来获取内核的数量,我发现其中只有两个似乎在32位或64位进程中准确工作.这是我的结果:
+------------------------------------------------+----------------+----------------+
| Methods | 32-bit process | 64-bit process |
+------------------------------------------------+----------------+----------------+
| GetSystemInfo->dwNumberOfProcessors | 32 | 36 |
| GetNativeSystemInfo->dwNumberOfProcessors | 36 | 36 |
| GetLogicalProcessorInformation | 36 | 36 |
| GetProcessAffinityMask.processAffinityMask | 32 | 32 |
| GetProcessAffinityMask.systemAffinityMask | 32 | 32 |
| omp_get_num_procs | 32 | 36 |
| getenv("NUMBER_OF_PROCESSORS") | 36 | 36 |
| GetActiveProcessorCount(ALL_PROCESSOR_GROUPS) | 64 | 72 | … 从这里开始,据说:
对于
#include "filename"预处理器,在与包含该指令的文件相同的目录中进行搜索.此方法通常用于包括程序员定义的头文件.对于
#include <filename>预处理器以依赖于实现的方式搜索,通常在编译器/ IDE预先指定的搜索目录中.此方法通常用于包括标准库头文件.
虽然这个wiki链接表明这stdafx.h是一个预先设计的头文件visual studio IDE
stdafx.h是一个由Microsoft Visual Studio IDE向导生成的文件,它描述了经常使用但几乎不会更改的标准系统和项目特定包含文件.
兼容的编译器(例如,Visual C++ 6.0和更新版本)将预编译此文件以减少整体编译时间.Visual C++不会在源文件中的#include"stdafx.h"之前编译任何内容,除非取消选中编译选项/Yu'stdafx.h'(默认情况下); 它假设源中包含该行的所有代码都已编译.
stdafx.h中的AFX代表Application Framework eXtensions.AFX是Microsoft基础类(MFC)的原始缩写.虽然默认使用名称stdafx.h,但项目可以指定替代名称.
然后
为什么我们使用#include "stdafx.h"而不是#include <stdafx.h>?
经过几天的痛苦调试,我可以通过这个小程序在我的单元测试中重现一个错误:
#include <iostream>
#include <vector>
#include <condition_variable>
#include <mutex>
#include <thread>
#include <chrono>
#include <new>
int main(){
try{
for(size_t j=0;j<100;++j){
std::cout<<j<<std::endl;
std::mutex mutex;
std::unique_ptr<std::condition_variable>cv;
std::vector<std::thread>v(10);
auto wait=[&](size_t i){
std::unique_lock<std::mutex>ul(mutex);
if(!cv){cv=std::make_unique<std::condition_variable>();}
cv->wait_for(ul,std::chrono::milliseconds(i*10));
};
for(size_t i=0;i<v.size();++i){v[i]=std::thread(wait,i);}
for(size_t i=0;i<v.size();++i){v[i].join();}}}
catch(...){
std::cout<<"Exception"<<std::endl;
std::abort();}
}
Run Code Online (Sandbox Code Playgroud)
当我用lmcheck编译时:
g++-4.9.2 -lmcheck -std=c++1y -pthread /home/Arnaud/Test.cpp -o Test
Run Code Online (Sandbox Code Playgroud)
程序运行和停止 memory clobbered before allocated block
我可以在多台机器上重现这一点,并使用gcc 4.9.2和gcc 5.1.这段代码有什么问题?
注意:此代码在Visual Studio 2013中运行良好.
c++ ×8
c++11 ×3
c ×2
copy ×1
directive ×1
gcc ×1
goto ×1
header-files ×1
include ×1
memory-leaks ×1
move ×1
mutex ×1
optimization ×1
qt ×1
qt5 ×1
return ×1
shared-ptr ×1
stdthread ×1
winapi ×1
windows ×1