小编Kie*_*etz的帖子

使用指针的整数值检查指针对齐是否真的定义良好?

是否有一种有保证的(不是实现定义的!)方法来检查指针对齐?

查询指针对齐的最常见方法似乎是:

  1. 转换为整数
  2. 检查整数是否是对齐的倍数:
bool is_aligned(void const *ptr, size_t alignment) {
  return reinterpret_cast<intptr_t>(ptr) % alignment == 0;
}
Run Code Online (Sandbox Code Playgroud)

例如,这就是Boost.Align 检查对齐方式的方式。

然而,至少在 C++17 中,basic.compound#3.4说:

指针类型的值表示是实现定义的。

此外,expr.reinterpret.cast#4说:

指针可以显式转换为任何足够大以容纳它的整型。映射函数是实现定义的。

(例如)将指针表示为具有相反位顺序的整数似乎是合法的,在这种情况下,上面的简单算术将不起作用。

AFAICT,我们可以检查对齐的唯一有保证的方法是使用std::align,如果自由地阅读(我确信这是对 的滥用std::align),可以像这样使用:

bool is_aligned(void const *ptr, size_t alignment) {
  void *mut_ptr = const_cast<void *>(ptr);
  size_t space = alignment;
  return std::align(alignment, alignment, mut_ptr, space) == ptr;
}
Run Code Online (Sandbox Code Playgroud)

然而,在绝大多数平台上,指针只是奇特的整数,或者我希望 Boost 有一个代码路径。是否有任何平台(除了 ds9k :P)其中指针不仅仅是花哨的整数?

通过标准化“应具有与”或“如果与”对齐reinterpret_cast<intptr_t>(ptr)相同的对象表示,我们会​​损失什么?似乎这些都不会排除分段内存或具有陷阱表示的指针,这是我能想到的两种非典型情况。ptrreinterpret_cast<intptr_t>(ptr) % alignment == 0ptr …

c++ pointers undefined-behavior language-lawyer c++17

16
推荐指数
1
解决办法
1133
查看次数

如果从dlopen'd库中调用dlopen(),是否存在负载泄漏?

如果我的可执行文件调用dlopen加载库但忽略调用dlclose,则库将保持加载状态,直到进程退出并且操作系统强制它卸载.

如果我加载a.so它会加载b.so,然后调用dlclosea.so,并在OS卸载b.so呢?

这与使用Microsoft等效的类似场景相比如何LoadLibraryEx

c++ dynamic-loading dlopen

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

为什么 ISO c++17 不允许在条件中使用结构化绑定声明?

如果我使用结构化绑定声明作为条件,Clang 会发出警告:

$ cat hello.cc
int main() {
  struct A { int i; operator bool() { return true; } };
  if (auto [i] = A{0}) {
    return i;
  }
  return -1;
}
Run Code Online (Sandbox Code Playgroud)
$ clang++-10 -std=c++17 hello.cc
hello.cc:3:12: warning: ISO C++17 does not permit structured binding declaration in a condition [-Wbinding-in-condition]                                                                                                                                                                               
  if (auto [i] = A{0}) {                                                                                                                                                                                                                                                                               
           ^~~                                                                                                                                                                                                                                                                                         
1 warning generated.
Run Code Online (Sandbox Code Playgroud)

我在dcl.struct.bindstmt.select中没有看到这一点;我在哪里可以看到这是禁止的?

此外:禁止这样做的理由是什么?

c++ language-lawyer

3
推荐指数
1
解决办法
393
查看次数

一个RenderScript内核可以重载吗?

我想重载一个RenderScript内核:

/* donothing.rs */

uchar4 __attribute__((kernel, overloadable)) root (uchar4 in) {
  return in;
}

float4 __attribute__((kernel, overloadable)) root (float4 in) {
  return in;
}
Run Code Online (Sandbox Code Playgroud)

但是,这会生成同名的Java方法:

// ScriptC_donothing.java:95
public void forEach_root(Allocation ain, Allocation aout, Script.LaunchOptions sc) {
    // check ain
    if (!ain.getType().getElement().isCompatible(__U8_4)) {
        throw new RSRuntimeException("Type mismatch with U8_4!");
    }
    ...

// ScriptC_donothing.java:225
public void forEach_root(Allocation ain, Allocation aout, Script.LaunchOptions sc) {
    // check ain
    if (!ain.getType().getElement().isCompatible(__F32_4)) {
        throw new RSRuntimeException("Type mismatch with F32_4!");
    }
    ...
Run Code Online (Sandbox Code Playgroud)

有没有办法编写内核以使重载有效?我预期的用法是:

// DoNothingActivity.java

mInAllocation = …
Run Code Online (Sandbox Code Playgroud)

overloading renderscript

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