小编Quu*_*one的帖子

为什么boost :: filesystem :: path和std :: filesystem :: path缺少operator +?

考虑以下关于路径分解的断言,其中每个局部变量例如stem具有明显的初始化,例如auto stem = path.stem()-

assert(root_path == root_name / root_directory);
assert(path == root_name / root_directory / relative_path);
assert(path == root_path / relative_path);

assert(path == parent_path / filename);
assert(filename == stem + extension);
Run Code Online (Sandbox Code Playgroud)

这一切都有效,除了最后一行 - 因为fs::path没有定义operator+.它有operator+=,但没有operator+.

这是什么故事?


我已经确定我可以通过添加自己的代码来编译代码operator+.有什么理由不这样做吗?(请注意,这是在我自己的命名空间中;我没有重新打开namespace std.)

fs::path operator+(fs::path a, const fs::path& b)
{
    a += b;
    return a;
}
Run Code Online (Sandbox Code Playgroud)

我对这个问题的唯一假设是:

  • 也许设计师担心operator+会太容易混淆使用std::stringoperator+.但这看起来很愚蠢,因为它在语义上完全相同(所以为什么要关心它是否会混淆?).而这也似乎设计师不关心新手的困惑,当他们设计path.append("x")做一些语义不同str.append("x")和 …

c++ boost-filesystem c++17

13
推荐指数
1
解决办法
670
查看次数

你能在内核模式之外输入x64 32位"长兼容子模式"吗?

这可能完全重复 是否可以通过模式切换在64位进程中执行32位代码?,但这个问题是从一年前开始的,只有一个答案没有给出任何源代码.我希望得到更详细的答案.

我正在运行64位Linux(Ubuntu 12.04,如果重要的话).这里有一些代码可以分配页面,将一些64位代码写入其中,然后执行该代码.

#include <assert.h>
#include <malloc.h>
#include <stdio.h>
#include <sys/mman.h>  // mprotect
#include <unistd.h>  // sysconf

unsigned char test_function[] = { 0xC3 };  // RET
int main()
{
    int pagesize = sysconf(_SC_PAGE_SIZE);
    unsigned char *buffer = memalign(pagesize, pagesize);
    void (*func)() = (void (*)())buffer;

    memcpy(buffer, test_function, sizeof test_function);

    // func();  // will segfault 
    mprotect(buffer, pagesize, PROT_EXEC);
    func();  // works fine
}
Run Code Online (Sandbox Code Playgroud)

现在,纯粹是为了娱乐价值,我想做同样的事情,但buffer包含任意32位(ia32)代码,而不是64位代码.此页面意味着您可以通过将CS段描述符的位设置为"长兼容性子模式"来在64位处理器上执行32位代码LMA=1, L=0, D=1.我愿意将我的32位代码包装在执行此设置的序言/结尾中.

但我可以在Linux中以usermode进行此设置吗?(BSD/Darwin的答案也将被接受.)这是我开始对这些概念感到朦胧的地方.我认为解决方案涉及向GDT添加新的段描述符(或者是LDT?),然后通过lcall指令切换到该段.但是所有这些都可以在usermode中完成吗?

这是一个示例函数,在兼容性子模式下成功运行时应返回4,在长模式下运行时应返回8.我的目标是获取指令指针以获取此代码路径并从另一端出来%rax=4,而不会进入内核模式(或仅通过记录的系统调用执行此操作). …

linux kernel x86-64 compatibility-mode

12
推荐指数
1
解决办法
1593
查看次数

为什么C++编译器不会从最终类中优化这个dynamic_cast?

考虑这个类层次结构:

struct Animal { virtual ~Animal(); };
struct Cat : virtual Animal {};
struct Dog final : virtual Animal {};
Run Code Online (Sandbox Code Playgroud)

我的理解是,将finalclass Dog确保没有人能够创建一个类继承Dog,其中,推论,意味着没有人能够创建IS-A类Dog和IS-A Cat同时进行.

考虑这两个dynamic_cast:

Dog *to_final(Cat *c) {
    return dynamic_cast<Dog*>(c);
}

Cat *from_final(Dog *d) {
    return dynamic_cast<Cat*>(d);
}
Run Code Online (Sandbox Code Playgroud)

GCC,ICC和MSVC忽略final限定符并生成调用__dynamic_cast; 这是不幸的,但并不令人惊讶.

让我感到惊讶的是,Clang和Zapcc都为("总是返回nullptr")生成了最佳代码from_final,但是生成了对__dynamic_castfor 的调用to_final.

这真的是一个错过的优化机会(在一个编译器中显然有人投入一些努力来尊重final演员阵容中的限定符),或者在这种情况下,由于某些微妙的原因,我仍然没有看到优化是不可能的?

c++ polymorphism dynamic-cast final

12
推荐指数
1
解决办法
397
查看次数

无法检测为什么下面的代码没有被矢量化

我一直在努力使用某个特定的应用程序,我已经尝试了一切.从自动向量化到手动编码的SSE内在函数.但不知何故,我无法在基于模板的应用程序上获得加速.

以下是我当前代码的片段,我使用SSE内在函数进行了矢量化.当我使用-vec-report3编译(Intel icc)时,我不断获取此消息:
remark:loop未向量化:语句无法向量化.

  #pragma ivdep
  for ( i = STENCIL; i < z - STENCIL; i+=4 )
  {
    it = it2 + i;

    __m128 tmp2i = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j4+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j4+k*it_k])),X4_i); //loop was not vectorized: statement cannot be vectorized
    __m128 tmp3 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j3+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j3+k*it_k])),X3_i);
    __m128 tmp4 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j2+k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j2+k*it_k])),X2_i);
    __m128 tmp5 = _mm_mul_ps(_mm_add_ps(_mm_load_ps(&p2[i+j*it_j-it_j +k*it_k]),_mm_load_ps(&p2[i+j*it_j+it_j +k*it_k])),X1_i);

    __m128 tmp6 = _mm_add_ps(_mm_add_ps(_mm_add_ps(tmp2i,tmp3),_mm_add_ps(tmp4,tmp5)), _mm_mul_ps(_mm_load_ps(&p2[it]),C00_i));

    _mm_store_ps(&tmp2[i],tmp6);

   }
Run Code Online (Sandbox Code Playgroud)

我错过了一些关键的东西吗 由于该消息没有说明为什么它不能被矢量化,我发现很难确定瓶颈.

更新: 仔细考虑了建议后,我按照以下方式调整了代码.我认为最好将其进一步分解,以确定实际上导致向量依赖性的语句.

//#pragma ivdep
  for ( i = STENCIL; i < z - STENCIL; i+=4 )
  {
    it = it2 + …
Run Code Online (Sandbox Code Playgroud)

c sse vectorization icc stencils

11
推荐指数
1
解决办法
1209
查看次数

Mutex在boost regex构造函数中断言

我正在使用boost 1.47 for Arm,使用Code Sourcery C++编译器(4.5.1),从Windows 7开始针对Ubuntu进行交叉编译.

当我们编译调试版本(即启用了断言)时,会触发一个断言:

pthread_mutex_lock.c:62: __pthread_mutex_lock: Assertion 'mutex->__data.__owner == 0' failed.
Run Code Online (Sandbox Code Playgroud)

在发布模式下编译时,不会触发断言并且程序正常工作(据我们所知).

这是在Ubuntu 10.x Arm板下发生的.

因此,似乎pthread_mutex_lock认为互斥锁是由与当前线程不同的线程设置的.在我的程序中,我们仍然是单线程的,通过在main中打印出pthread_self来验证,并且在调用正则表达式构造函数之前.也就是说,断言不应该失败.

下面是触发问题的代码片段.

// Set connection server address and port from a URL
bool MyHttpsXmlClient::set_server_url(const std::string& server_url)
{
#ifdef BOOST_HAS_THREADS
cout <<"Boost has threads" << endl;
#else
cout <<"WARNING: boost does not support threads" << endl;
#endif
#ifdef PTHREAD_MUTEX_INITIALIZER
    cout << "pthread mutex initializer" << endl;
#endif
{
        pthread_t id = pthread_self();
        printf("regex: Current threadid: %d\n",id);
}
const boost::regex e("^((http|https)://)?([^:]*)(:([0-9]*))?"); // 2: …
Run Code Online (Sandbox Code Playgroud)

c++ regex linux boost initialization

11
推荐指数
1
解决办法
890
查看次数

lambda中捕获变量的decltype():GCC bug和/或Clang bug?

我已经检查了GCC buglistClang buglist,但还没有看到任何相关内容.

这个Wandbox链接显示了一些C++ 11/C++ 14代码的运行decltype(x)以及lambda捕获的decltype((x))各种代码x.GCC和Clang为此代码提供了不同的答案.其中哪一个,如果是,是正确的?

这是令人讨厌的片段:

// inside main()
int i = 42;
int &j = i;
[j=j](){
    static_assert(std::is_same<decltype(j), GCC(const) int>::value,""); // A
    static_assert(std::is_same<decltype((j)), const int&>::value,""); // B
}();
[=](){
    static_assert(std::is_same<decltype(j), int&>::value,""); // C
    static_assert(std::is_same<decltype((j)), CLANG(const) int&>::value,""); // D
}();
Run Code Online (Sandbox Code Playgroud)

哪里:

#ifdef __clang__
 #define CLANG(x) x
 #define GCC(x)
#else
 #define GCC(x) x
 #define CLANG(x)
#endif
Run Code Online (Sandbox Code Playgroud)

我相信在这两种情况下,实际捕获的东西(*)是一个(非常量)int初始化为一个j值的副本(也就是说,它i的值).由于lambda未标记mutable,operator()因此它将成为 …

c++ lambda decltype c++11 c++14

11
推荐指数
1
解决办法
286
查看次数

`string.assign(string.data(), 5)` 是定义明确的还是 UB?

一个同事想写这个:

std::string_view strip_whitespace(std::string_view sv);

std::string line = "hello  ";
line = strip_whitespace(line);
Run Code Online (Sandbox Code Playgroud)

我说返回string_view让我先验地感到不安,而且,这里的别名对我来说看起来像 UB。

我可以肯定地说,line = strip_whitespace(line)在这种情况下相当于line = std::string_view(line.data(), 5). 我相信会调用string::operator=(const T&) [with T=string_view],其定义为等价于line.assign(const T&) [with T=string_view],其定义为等价于line.assign(line.data(), 5),其定义为:

Preconditions: [s, s + n) is a valid range.
Effects: Replaces the string controlled by *this with a copy of the range [s, s + n).
Returns: *this.
Run Code Online (Sandbox Code Playgroud)

但这并没有说明出现混叠时会发生什么。

我昨天在 cpplang Slack 上问了这个问题,得到的答案喜忧参半。在这里寻找超级权威的答案,和/或对真实图书馆供应商实施的实证分析。


我写测试用例string::assignvector::assign …

c++ stl undefined-behavior

11
推荐指数
1
解决办法
213
查看次数

argparse:压扁action ='append'的结果

我想创建一个支持表单参数列表的脚本

./myscript --env ONE=1,TWO=2 --env THREE=3
Run Code Online (Sandbox Code Playgroud)

这是我的尝试:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
    '--env',
    type=lambda s: s.split(','),
    action='append',
)
options = parser.parse_args()
print options.env

$ ./myscript --env ONE=1,TWO=2 --env THREE=3
[['ONE=1', 'TWO=2'], ['THREE=3']]
Run Code Online (Sandbox Code Playgroud)

当然我可以在后处理中解决这个问题:

options.env = [x for y in options.env for x in y]
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有一些方法可以直接从argparse获取扁平列表,这样我就不必在脑中保留一个"事后我需要扁平化的东西"列表,因为我正在添加新的选项到程序.

如果我使用nargs='*'而不是使用相同的问题type=lambda....

import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
    '--env',
    nargs='+',
    action='append',
)
options = parser.parse_args()
print options.env

$ ./myscript --env ONE=1 TWO=2 --env THREE=3
[['ONE=1', 'TWO=2'], ['THREE=3']]
Run Code Online (Sandbox Code Playgroud)

python argparse

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

我可以在Xcode中指定自己的"线程名称"吗?

Xcode的"线程列表"窗格显示了几个特殊线程的英文名称:com.apple.main-thread,com.apple.libdispatch-manager,com.dispatchfractal.opencl,com.dispatchfractal.opengl,com.apple.root.低优先级,但对于用户创建的线程,该字段只是空白.

有没有办法从我的应用程序以编程方式设置"线程名称"字段?例如,如果我有一个专门用于网络I/O的线程,我希望它在调试器中显示为"com.example.network-io"; 如果我生成五个工作线程,我希望能够将它们命名为"worker A","worker B"等.Xcode是否可以从我可以挂钩的某些API中获取其线程名称?也许是这样的CFAssignDebuggerNameToCurrentThread?:)

在此输入图像描述

xcode multithreading nsthread

9
推荐指数
1
解决办法
3512
查看次数

在C++中实现"contextmanager"的最佳实践+语法

我们的Python代码库具有与度量相关的代码,如下所示:

class Timer:
    def __enter__(self, name):
        self.name = name
        self.start = time.time()

    def __exit__(self):
        elapsed = time.time() - self.start
        log.info('%s took %f seconds' % (self.name, elapsed))

...

with Timer('foo'):
    do some work

with Timer('bar') as named_timer:
    do some work
    named_timer.some_mutative_method()
    do some more work
Run Code Online (Sandbox Code Playgroud)

在Python的术语中,计时器是一个上下文管理器.

现在我们想在C++中实现相同的东西,同样好的语法.不幸的是,C++没有with.所以"明显的"成语将是(经典的RAII)

class Timer {
    Timer(std::string name) : name_(std::move(name)) {}
    ~Timer() { /* ... */ }
};

if (true) {
    Timer t("foo");
    do some work
}
if (true) {
    Timer named_timer("bar");
    do …
Run Code Online (Sandbox Code Playgroud)

c++ raii contextmanager c++11

9
推荐指数
3
解决办法
2079
查看次数