小编Max*_*dov的帖子

在g ++中使用符号'_end'会导致分段错误

考虑以下c ++源代码:

int _end[1050];

int main() {
    for (int i = 0; i < 1050; i++)
        _end[i] = 0;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译线: g++ main.cpp -o main -O0

在Ubuntu 14.04下使用gcc-4.8.4和clang-3.6.0时,运行此代码会导致分段错误.奇怪的行为是符号_end指向静态分配的数组的末尾_end,而不是它的开头.如果我们替换_endend_,一切工作正常.

此外,如果我们要求gcc通过提供-S命令行参数输出汇编代码,则带有"_end"的版本与具有任何其他数组名称的版本之间没有显着差异:

$ g++ main.cpp -o main.s -O0 -S
$ g++ main2.cpp -o main2.s -O0 -S
$ diff main.s main2.s
1,2c1,2
<   .file   "main.cpp"
<   .globl  _end
---
>   .file   "main2.cpp"
>   .globl  end_
5,7c5,7
<   .type   _end, @object
<   .size   _end, 4200 …
Run Code Online (Sandbox Code Playgroud)

linker gcc clang

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

SFINAE用于检测非成员模板功能的存在

TL; DR我想写一个模板函数Process(T value),根据非成员函数的存在,它对不同的值表现不同CreateProcessor<T>().我能做些什么?

我有SFINAE的问题.假设我们需要支持CreateProcessor返回IProcessor<T>某种类型类型的接口实现的函数T.

在C++中,我们不能创建仅在返回类型上有所不同的函数的多个重载,因此我们必须使函数CreateProcessor也是由参数化的模板函数T.

现在假设我们要编写一个模板函数Process<T>(T value),它根据存在的不同而工作CreateProcessor<T>(),即它应该valueCreateProcessor<T>()实现的情况下使用处理器进行处理,否则会导致错误.

我试图编写以下代码:

#include <cstdio>
#include <type_traits>

// A workaround for void_t as described here: http://en.cppreference.com/w/cpp/types/void_t.
template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;

// An interface for a processor that receives a value of specific type.
template<class T>
class IProcessor {
public:
    virtual void …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae template-meta-programming

6
推荐指数
1
解决办法
311
查看次数

假设经过源缓冲区和目标缓冲区的字节具有可读性和可写性,则 memcpy 速度更快

假设我们想要将n数据字节从void* src复制到void* dst。众所周知,标准库的实现经过memcpy严格优化,可以使用依赖于平台的向量化指令和各种其他技巧来尽可能快地执行复制。

现在假设p后面的数据字节src + n是可读的并且p后面的数据字节dst + n是可写的。另外,假设在 中写入任意垃圾也是可以的[dst + n, dst + n + p)

显然,这些假设扩大了我们可能采取的行动的范围,可能导致更快的 memcpy。例如,我们可以在少量未对齐的 128 位指令(加载 + 存储)中复制少于 16 个尾随字节的某些部分。也许这种额外的假设还允许使用其他技巧。

     01234 .....            n
src: abcdabcdabcdabcdabcdabcGARBAGEGA
            v              v 
dst: ______(actl dst)________(wrtbl)_
     |    block1    ||    block2    |
Run Code Online (Sandbox Code Playgroud)

请注意,当您需要在分配的容量足以容纳p+ 总字符串大小字节的缓冲区内附加字符串序列时,这些假设实际上相当实用。例如,以下例程可能发生在数据库内部的某个位置:

给你一个二进制字符串char* dictionary和一个整数数组 int* offsets,它是字典中偏移量的单调序列;这两个变量表示从磁盘获取的字符串字典。您还有一个整数数组,int* indices指示必须将字典字符串写入输出缓冲区的顺序 char* buffer

使用上述技术,您可以安全地编写每个新字符串,而不关心其右侧的垃圾,因为它将被要附加的下一个字符串覆盖。

问题是:

  1. 这种技术有开源实现吗?实现最佳实现显然需要花费大量时间进行(依赖于平台的)调整,因此在不考虑现有实现的情况下编写此类代码似乎不是一个好主意。
  2. 为什么分配后 15 个字节的可读性不是现代分配器的功能?如果内存分配器可以在其内部执行的每个 …

c c++ simd memcpy allocator

5
推荐指数
1
解决办法
178
查看次数

标签 统计

c++ ×2

allocator ×1

c ×1

clang ×1

gcc ×1

linker ×1

memcpy ×1

sfinae ×1

simd ×1

template-meta-programming ×1

templates ×1