小编Emi*_*mil的帖子

C++私有函数的内部链接?

当我在C中编写面向对象的代码时,我通常将结构定义与公共函数一起放在头文件中,并在单独的.c文件中实现公共函数.我将static关键字赋给此类的所有"私有"函数,并在.c文件中实现它们.然后,公共函数可以调用属于同一类的私有函数.由于static关键字,私有函数无法从外部调用,因此GCC可以优化其中许多函数.它们经常被内联,原始函数完全从输出对象文件中删除.

现在我的问题是:我怎么能用C++类做同样的事情?

假设我有一个头文件:

class A {
    int private_field;
    int private_function();
public:
    int public_function();
};
Run Code Online (Sandbox Code Playgroud)

我的.cpp文件:

#include <iostream>
#include "A.h"

int A::private_function() {
    std::cin >> private_field;
    return private_field;
}

int A::public_function() {
    return private_function() + 4;
}
Run Code Online (Sandbox Code Playgroud)

在生成的目标文件中,private_function保留为单独的符号,public_function调用private_function(未内联).我想提供private_function内部链接,因此编译器可以执行与使用C时相同的优化.我尝试过使用匿名命名空间和静态,但我无法按照我的意愿使用它.如何正确地做到这一点,甚至可能吗?我用GCC.

c++ private

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

为什么非可变 lambda 中的字段在捕获常量值或常量引用时使用“const”?

正如问题lambda capture by value mutable 中所见,它不适用于 const &? , 当const T&使用其名称或[=]可变 lambda捕获类型的值时,隐藏类中的字段获取类型const T。可以争论的是,这对于可变 lambda 来说是正确的做法。

但是为什么对非可变 lambda 也这样做呢?在非可变 lambda 表达式中,operator()(...)is 被声明const,因此无论如何它都不能修改捕获的值。

当我们移动 lambda 时,例如将它包装在std::function.

请参阅以下两个示例:

#include <cstdio>
#include <functional>

std::function<void()> f1, f2;

struct Test {
    Test() {puts("Construct");}
    Test(const Test& o) {puts("Copy");}
    Test(Test&& o) {puts("Move");}
    ~Test() {puts("Destruct");}
};

void set_f1(const Test& v) {
    f1 = [v] () {}; // field type in lambda object will be …
Run Code Online (Sandbox Code Playgroud)

c++ lambda constants mutable language-lawyer

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

Java 8:验证字节码时将 String[] 和 int[] 合并到 Object[] 中

我正在阅读 JVM 版本 8 规范的第 4.10.2.2 节(https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html)如何验证字节码。在这种情况下,当堆栈现在包含一个槽时,如果来自一个源,则包含一个 int[] ;如果来自另一个源,则包含一个 String[] ,控制流中会发生什么情况。

我阅读了以下内容,该内容在 JVM 版本 7 文档中不存在:

如果对应的值都是数组引用类型,则检查它们的维度。如果数组类型具有相同的维度,则合并的值是对数组类型实例的引用,该数组类型是两种数组类型的第一个公共超类型。(如果其中一个或两个数组类型具有原始元素类型,则使用 Object 作为元素类型。)

...

甚至int[]和String[]也可以合并;结果是 Object[],因为在计算第一个公共超类型时使用了 Object 而不是 int。

这对我来说没有任何意义,因为这意味着 int[] 可以转换为 Object[]。但在 Java 中,原始类型的数组不能转换为 Object[]。

谁能解释一下这背后的理由吗?

java jvm bytecode jvm-bytecode

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

LLVM insertvalue糟糕优化?

当我发出LLVM代码时,我应该避免使用'insertvalue'指令结合加载和存储吗?当我使用它时,我总是得到错误的优化本机代码.请看以下示例:

; ModuleID = 'mod'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-pc-linux-gnu"

%A = type { i64, i64, i64, i64, i64, i64, i64, i64 }

@aa = external global %A*

define void @func() {
entry:
  %a1 = load %A** @aa
  %a2 = load %A* %a1
  %a3 = insertvalue %A %a2, i64 3, 3
  store %A %a3, %A* %a1
  ret void
}
Run Code Online (Sandbox Code Playgroud)

当我运行"llc -o - -O3 mod.ll"时,我得到了这个可怕的代码:

func:                                   # @func
.Ltmp0:
        .cfi_startproc
# BB#0:                                 # %entry
        movq    aa(%rip), %rax
        movq …
Run Code Online (Sandbox Code Playgroud)

optimization code-generation x86-64 llvm

5
推荐指数
0
解决办法
401
查看次数

告诉LLVM优化器变量的内容

我正在编写一个使用LLVM作为后端的编译器,并且有很多引用计数.当我借用一个对象时,我会增加对象的引用计数器.当我释放一个对象时,我减少了参考计数器,并在它变为零时释放该对象.但是,如果我只做一小段代码,就像这样:

++obj->ref;
global_variable_A = obj->a;
if (--obj->ref == 0)
    free_object(obj);
Run Code Online (Sandbox Code Playgroud)

LLVM将此优化为(在IR中,但这是C中的相等代码):

global_variable_A = obj->a;
if (obj->ref == 0)
    free_object(obj);
Run Code Online (Sandbox Code Playgroud)

但是因为我知道在第一个语句之前引用计数器总是正数,所以它只能被优化

global_variable_A = obj->a;
Run Code Online (Sandbox Code Playgroud)

我的问题:有没有办法告诉LLVM优化器,在读取它时,寄存器或某些内存是否包含非零数据?

另一个相同的问题是,如果我可以告诉优化器指针是非空的,那也很好.

compiler-construction optimization llvm

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

HttpURLConnection 的套接字被泄露

我在 Linux 上使用 OpenJDK 11,我需要确保使用 HttpURLConnection 完成的所有 Web 请求都已正确关闭,并且不打开任何文件描述符。

甲骨文手册讲述使用closeInputStreamAndroid的手册告诉编译器使用disconnect的上HttpURLConnection对象。

我还设置Connection: closehttp.keepAlivefalse避免连接池。

这似乎适用于普通的http请求,但不适用于其响应以非分块编码发送的加密https请求。似乎只有 GC 会清理关闭的连接。

此示例代码:

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;

public class Test {
    private static int printFds() throws IOException {
        int cnt = 0;
        try (Stream<Path> paths = Files.list(new File("/proc/self/fd").toPath())) {
            for …
Run Code Online (Sandbox Code Playgroud)

java connection-leaks httpurlconnection

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