小编Arn*_*aud的帖子

有效使用goto进行C中的错误管理?

这个问题实际上是不久前在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

c error-handling exception-handling goto

88
推荐指数
5
解决办法
2万
查看次数

使用std :: lock的大量CPU负载(c ++ 11)

我最近实现线程/互斥管理器的努力最终导致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)

c++ mutex c++11 stdthread

31
推荐指数
3
解决办法
7393
查看次数

std :: shared_ptr例外安全

我刚刚意识到阅读这个页面,std :: shared_ptr的构造函数与单个指针参数不是noexcept.

因此,以下代码包含可能的内存泄漏:

std::shared_ptr<int> p3 (new int);
Run Code Online (Sandbox Code Playgroud)

原因是可能发生两次分配:

  • 在调用构造函数之前的第一个
  • shared_ptr构造函数中的第二个(例如VS 2012中发生的情况)

这里有两个问题:

如果第二个分配抛出异常,第一个分配的内存泄漏,这是真的吗?

如果答案是肯定的:

使用std :: shared_ptr的正确习惯用法是什么?

  • 使用make_shared
  • 将第一个分配的所有权赋予std :: unique_ptr然后转移所有权
  • 其他想法 ?

c++ memory-leaks shared-ptr c++11

30
推荐指数
2
解决办法
3659
查看次数

如何重置Visual Studio中的跟踪更改?

我正在使用Visual Studio,我非常喜欢轨道更改功能:

过了一会儿,我正在编辑的文件完全是绿色的.当它发生时,我想清除所有的标记.

我找到了三种方法,但它们并不像我想的那么简单:

  • 关闭并重新打开Visual Studio.

  • 关闭并重新打开所有文件.

  • 打开选项对话框,取消选中该功能,重新打开对话框并重新检查功能. 在此输入图像描述

有一条神奇的捷径吗?

visual-studio visual-studio-2012

22
推荐指数
1
解决办法
2854
查看次数

高效计算32位整数乘法的高阶位

许多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版本,就像我在寻找.

c c++ optimization

10
推荐指数
1
解决办法
2569
查看次数

使用Visual Studio 2013构建Qt 5.2.1的静态版本

我已经尝试了几天用Visual Studio 2013构建静态版本的Qt.我只是无法弄清楚我做错了什么.

系统:

  • Windows 7 64位
  • Visual Studio 2013(仍安装Visual Studio 2012)
  • 已安装Perl(ActivePerl-5.18.2.1801-MSWin32-x64-297964.msi)
  • 安装了Python(python-2.7.6.amd64.msi)
  • 安装了Direct X 10 SDK(DXSDK_Jun10.exe我不得不使用此解决方法)
  • 下载Qt 5.2.1
  • 下载Qt 5.3.0 alpha

我多次做了什么:

  • 提取临时文件夹中的源(C:\ QtSrc)
  • 删除qtwebkit和qtwebkit-examples目录

对于每个文件夹,我启动了Visual Studio x86命令行并运行:

  • cd C:\ QtSrc
  • configure -c ++ 11 -mp -debug-and-release -static -angle -nomake tests -nomake examples -prefix C:\ Qt\5.2.1\msvc2013 -platform win32-msvc2013
  • NMAKE
  • nmake安装

对于我试过的-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)

c++ qt static-libraries visual-studio qt5

8
推荐指数
1
解决办法
5181
查看次数

何时返回函数外部的值使用move vs copy?

看完这个问题后.我创建了这个小小的测试:

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):

  • f使用移动
  • g使用移动
  • h使用副本

据我所知,用于决定是否使用复制或移动的规则在12.8.32中描述:

  • 满足或将满足复制操作的省略标准时,除了源对象是函数参数这一事实,并且要复制的对象由左值指定,重载决策选择复制的构造函数是首先执行,好像对象是由右值指定的....

这是指12.8.31的规则:(我只显示相关部分)

  • 在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cvunqualified类型的非易失性自动对象(函数或catch子句参数除外)的名称时,副本通过将自动对象直接构造到函数的返回值中,可以省略/ move操作
  • 当一个未绑定到引用(12.2)的临时类对象被复制/移动到具有相同cv-nonqualified类型的类对象时,可以通过将临时对象直接构造到目标中来省略复制/移动操作省略的复制/移动

按照这些规则,我理解f和h会发生什么:

  • f中的副本有资格获得elision,因此被移动.(参见粗体部分)
  • h中的副本不符合elision的条件,因此会被复制.

怎么样?

对我来说,它看起来很像h.我正在返回一个表达式,它不是自动对象的名称,因此我认为它会被复制但是它被移动了.这里发生了什么?

c++ copy return move c++11

8
推荐指数
1
解决办法
446
查看次数

以可编程方式获取Windows上硬件线程数的可靠方法

我很难找到一种可靠的方法来获取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 | …

c++ windows winapi multithreading

8
推荐指数
1
解决办法
1152
查看次数

为什么我们使用`#include"stdafx.h"`而不是`#include <stdafx.h>`?

这里开始,据说:

对于#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>

c++ directive include header-files visual-studio-2010

8
推荐指数
1
解决办法
2万
查看次数

在分配块之前被破坏的内存

经过几天的痛苦调试,我可以通过这个小程序在我的单元测试中重现一个错误:

#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++ multithreading gcc memory-management

7
推荐指数
1
解决办法
1067
查看次数