小编MrM*_*ter的帖子

用C++重新解释这个:合法与否?

这是一个有点深奥的问题,但我很好奇以下类扩展模式在现代C++中是否合法(如,不构成UB)(出于所有目的和目的,我将讨论局限于C++ 17和后来).

template<typename T>
struct AddOne {
    T add_one() const {
        T const& tref = *reinterpret_cast<T const*>(this);
        return tref + 1;
    }
};

template<template<typename> typename  E, typename T>
E<T> const& as(T const& obj) {
    return reinterpret_cast<E<T> const&>(obj);
} 

auto test(float x) {
    return as<AddOne>(x).add_one();
}

auto test1(int x) {
    return as<AddOne>(x).add_one();
}

// a main() to make this an MVCE
// will return with the exit code 16
int main(int argc, const char * argv[]) {
  return test1(15);
}
Run Code Online (Sandbox Code Playgroud)

上面的代码是一个完整的例子,它在C++ …

c++ language-lawyer reinterpret-cast c++17

9
推荐指数
2
解决办法
529
查看次数

Rails PostgreSQL套接字路径

假设我运行了一个Postgres集群,其Unix域套接字位于/ some/custom/path下

如何设置我的database.yml以便Rails应用程序可以连接到群集?

postgresql ruby-on-rails

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

通过 Rust 宏自定义文字?

是否可以在 Rust 中定义一个可以解析自定义文字的宏,例如

vector!(3x + 15y)
Run Code Online (Sandbox Code Playgroud)

澄清一下,我希望能够尽可能接近上述语法(当然在可能的范围内)。

rust rust-macros

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

用bash异步消耗管道

我有这样的bash脚本

data_generator_that_never_guits | while read data 
do
 an_expensive_process_with data
done
Run Code Online (Sandbox Code Playgroud)

第一个过程连续生成事件(以不规则的间隔),需要在它们可用时进行处理.这个脚本的一个问题是read on消耗了一行输出; 由于处理非常昂贵,我希望它能够使用当前可用的所有数据.另一方面,如果有新数据可用,则必须立即开始处理.简而言之,我想做这样的事情

data_generator_that_never_guits | while read_all_available data 
do
 an_expensive_process_with data
done
Run Code Online (Sandbox Code Playgroud)

如果没有数据可供使用,命令read_all_available将等待,或者将所有当前可用数据复制到变量.如果数据不是由实线组成,那就完全没了问题.基本上,我正在寻找一个读取模拟,它将读取整个管道缓冲区而不是从管道中读取一行.

对于你们之间的好奇,我有一个需要触发源文件重建的构建脚本的问题的背景会发生变化.我想避免经常触发重建.请不要建议我使用grunt,gulp或其他可用的构建系统,它们不能很好地用于我的目的.

谢谢!

shell pipe producer-consumer

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

联盟和C11中的严格别名

假设我有这样的联盟

union buffer {
  struct { T* data; int count; int capacity; };
  struct { void* data; int count; int  capacity; } __type_erased;
};
Run Code Online (Sandbox Code Playgroud)

如果我在C11别名规则下将读/写混合到匿名结构成员和__type_erased成员,我会遇到麻烦吗?

更具体地说,我感兴趣的是如果独立访问组件(例如通过不同的指针)会发生的行为.为了显示:

grow_buffer(&buffer.__type_erased);
buffer.data[buffer.count] = ...
Run Code Online (Sandbox Code Playgroud)

我已经阅读了所有可以找到的相关问题,但我仍然没有100%明确这一点,因为有些人似乎认为这种行为是不明确的,而其他人则认为这是合法的.此外,我发现的信息是C++,C99,C11等规则的混合,很难消化.在这里,我对C11强制要求的行为以及流行编译器(Clang,GCC)展出的行为感兴趣

编辑:更多信息

我现在已经对多个编译器进行了一些实验,并决定分享我的发现以防有人遇到类似的问题.我的问题的背景是我试图在简单的C中编写一个用户友好的高性能通用动态数组实现.想法是使用宏执行数组操作并且重载操作(如增长数组)是使用别名类型擦除的模板结构执行.例如,我可以像这样的宏:

#define ALLOC_ONE(A)\
    (_array_ensure_size(&A.__type_erased, A.count+1), A.count++)
Run Code Online (Sandbox Code Playgroud)

必要时增长数组并返回新分配项的索引.规范(6.5.2.3)规定允许通过不同的联盟成员访问同一位置.我对此的解释是,虽然_array_ensure_size()不知道union类型,但编译器应该知道成员__type_erased可能会因副作用而发生变异.也就是说,我认为这应该有效.但是,这似乎是一个灰色区域(说实话,规范实际上并不清楚成员访问的构成).Apple的最新Clang(clang-800.0.33.1)没有任何问题.代码编译时没有警告,并按预期运行.但是,当使用GCC 5.3.0编译时,代码会因段错误而崩溃.事实上,我强烈怀疑GCC的行为是一个错误 - 我试图通过删除可变指针引用并采用明确的功能样式来明确联合成员变异,例如:

#define ALLOC_ONE(A) \
   (A.__type_erased = _array_ensure_size(A.__type_erased, A.count+1),\
    A.count++)
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,这再次与Clang合作,但再次崩溃了GCC.我的结论是,使用工会进行先进式操作是一个灰色区域,人们应该谨慎行事.

strict-aliasing unions language-lawyer c11

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

在函数参数中解构包含借位的结构

我正在尝试实现一个使用借用检查/生命周期的系统,以便为集合提供安全的自定义索引.请考虑以下代码:

struct Graph(i32);

struct Edge<'a>(&'a Graph, i32);

impl Graph {
    pub fn get_edge(&self) -> Edge {
        Edge(&self, 0)
    }

    pub fn split(&mut self, Edge(_, edge_id): Edge) {
        self.0 = self.0 + edge_id;
    }

    pub fn join(&mut self, Edge(_, edge0_id): Edge, Edge(_, edge1_id): Edge) {
        self.0 = self.0 + edge0_id + edge1_id;
    }
}


fn main() {
    let mut graph = Graph(0);
    let edge = graph.get_edge();
    graph.split(edge)
}
Run Code Online (Sandbox Code Playgroud)

Edge当调用诸如splitjoin调用方法时,应删除对结构借用的图形的引用.这将满足API不变量,即在图形变异时必须销毁所有边缘索引.但是,编译器没有得到它.它失败的消息就像

error[E0502]: cannot borrow `graph` as mutable because …
Run Code Online (Sandbox Code Playgroud)

struct rust borrow-checker

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

在初始化内存上使用placement new是否合法?

我正在探索在C++中实现真(部分)不可变数据结构的可能性.由于C++似乎没有区分变量和变量存储的对象,因此真正替换对象(没有赋值操作!)的唯一方法是使用placement new:

auto var = Immutable(state0);
// the following is illegal as it requires assignment to
// an immutable object
var = Immutable(state1);
// however, the following would work as it constructs a new object
// in place of the old one
new (&var) Immutable(state1);
Run Code Online (Sandbox Code Playgroud)

假设没有非平凡的析构函数可以运行,这在C++中是合法的还是我应该期望未定义的行为?如果它依赖于标准,那么我可以期待这个最小/最大标准版本能够工作吗?

c++ memory placement-new language-lawyer

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

C实现中的浮点零(IEEE 754不变量?)

我有一个以下的C表达式(变量是32位浮点数)

float result = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0)
Run Code Online (Sandbox Code Playgroud)

假设x0==x1y0==y1,(并且==我的意思是二进制表示形式),我可以依赖表达式必须求值为零的事实(例如,浮点数的所有位都设置为0)?换句话说,我可以假设跟随不变量总是持有吗?

memcmp(&a, &b, sizeof(float) == 0 => memcmp(a-b, (uint32_t)0, sizeof(float)) == 0
0*a == 0.0
Run Code Online (Sandbox Code Playgroud)

可以安全地假设所有值都是有限数(无INFINITY或NaN).

编辑:正如答案中所指出的,乘以0会产生带符号的零.我仍然可以依赖于使用FP比较规则表达式的结果将等于0.0的事实,即:

(result == 0.0) 
Run Code Online (Sandbox Code Playgroud)

编辑1:通过memcmp调用替换类型转换以更好地说明问题.

PS我只是将我的代码限制在兼容的C11编译器中,以防它有任何区别.如果这对我的情况有帮助,我也愿意依赖STDC_IEC_559支持.

c numeric zero ieee-754

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

约束父特征以引用

我想定义一个特征Container,使得这个特征的每个实现者也需要实现IntoIterator,但需要注意的是迭代总是只能借用实例.如果我理解正确,我可以IntoIterator使用这样的模式实现:

impl<'a> IntoIterator for &'a ContainerImpl
Run Code Online (Sandbox Code Playgroud)

但是,如果类型实现Container,我如何指定这需要实现,例如:

trait Container: &IntoIter ???
Run Code Online (Sandbox Code Playgroud)

iterator traits rust

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

稳健的线性插值

给定两个线段端点 A 和 B(在二维中),我想根据值 t 执行线性插值,即:

C = A + t(B-A)
Run Code Online (Sandbox Code Playgroud)

在理想世界中,A、B 和 C 应该共线。但是,我们在这里使用有限的浮点运算,所以会有小的偏差。为了解决其他操作的数值问题,我使用了最初由 Jonathan Shewchuk 创建的强大的自适应例程。特别是,Shewchuk 实现了一个方向函数orient2d,该函数使用自适应精度来精确测试三个点的方向。

我的问题是:是否有一个已知的程序如何使用浮点数学计算插值,以便它正好位于 A 和 B 之间的线上?在这里,我不太关心插值本身的准确性,而更关心由此产生的共线性。换句话说,只要满足共线性,C 稍微移动一点就可以了。

precision geometry

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