小编acm*_*acm的帖子

文件范围的原子是否受初始化顺序惨败的影响?

请考虑以下内容,其中我们在不同的转换单元中有两个文件范围的对象,这是通过初始化顺序fiasco的未定义行为的常规设置:

a.hpp:

struct thing {
public:
    thing(int value);
    ~thing();

    int value() const;

    static int count();

private:
    int _value;
};
Run Code Online (Sandbox Code Playgroud)

a.cpp:

#include "a.hpp"

#include <atomic>

namespace {
    std::atomic<int> things;
}

thing::thing(int value) : _value(value) {
    ++things;
}

thing::~thing() {
    --things;
}

int thing::value() const {
    return _value;
}

int thing::count() {
    return things.load();
}
Run Code Online (Sandbox Code Playgroud)

b.cpp:

#include <iostream>

#include "a.hpp"

namespace {
    thing static_thing(42);
}

void foo() {
    std::cout << static_thing.value() << ' ' << thing::count() << '\n';
} …
Run Code Online (Sandbox Code Playgroud)

c++ static initialization undefined-behavior c++11

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

什么是C++ 11原子API相当于```__asm__ volatile("":::"memory")```

代码库有一个COMPILER_BARRIER定义为的宏__asm__ volatile("" ::: "memory").宏的目的是防止编译器跨屏障重新排序读取和写入.请注意,这显然是编译器障碍,而不是处理器级别的内存障碍.

因此,这是相当便携的,因为AssemblerTemplate中没有实际的汇编指令,只有volatilememoryclobber.因此,只要编译器遵循GCC扩展Asm语法,它就可以正常工作.尽管如此,我很好奇如果可能的话,在C++ 11 atomics API中表达它的正确方法是什么.

以下似乎可能是正确的想法:atomic_signal_fence(memory_order_acq_rel);.

我的理由是:

  • <atomic>API中,仅需要atomic_signal_fence并且atomic_thread_fence不需要用于操作的存储器地址.
  • atomic_thread_fence 影响内存排序,我们不需要编译器障碍.
  • memoryExtended Asm版本中的clobber不区分读取和写入,因此看起来我们需要获取和释放语义,因此memory_order_acq_rel似乎至少需要.
  • memory_order_seq_cst 似乎没必要,因为我们不需要跨线程的总顺序 - 我们只对当前线程中的指令排序感兴趣.

是否有可能__asm__ volatile("" ::: "memory")用C++ 11 atomics API 表达完全可移植的等价物?如果是这样,是否atomic_signal_fence使用正确的API?如果是这样,这里适当/需要什么内存顺序参数?

或者,我在这里的杂草中,有一个更好的方法来解决这个问题吗?

c++ portability atomicity barrier c++11

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

为什么libcxx应用__forceinline或GCC等效于其已隐藏的内联函数?

我想明白为什么内联函数的libc ++可见性宏使用__forceinline__attribute__((__always_inline__))作为与内联函数关联的属性的一部分.

有关背景,请参阅

如果这些内联函数将被标记为__visibility__("hidden")无论如何,为什么还需要强制编译器内联它们?

我已经考虑了一下,我有一些假设,但似乎没有一个对我完全满意:

  • 这是为了确保符号不会意外地成为ABI的一部分.如果在构建库时,编译器选择不内联函数,它可能会成为外部符号,因此成为ABI的一部分.但这个hidden属性不足够吗?同样,在构建库时是否只需要强制内联函数?消费者不应该在意.
  • 这是为了确保函数永远不会有定义,以避免ODR问题,编译器选择不在库本身中内联函数,并选择不在函数中嵌入由库的客户端生成的代码,产生两种不同的定义.但这不是预期(和接受)使用的结果visibility("hidden")吗?
  • 它是libc ++设计中特定的东西,作为标准库的实现.

我问这个是因为我正在构建一个C++库,我希望有一天能够标准化ABI,我正在使用libc ++作为指导.到目前为止,它运作良好,但这个问题引起了一些人头疼.

特别是,我们有报道称用户抱怨MSVC拒绝遵守该__forceinline属性,从而导致警告.我们提出的解决方案是__forceinline在构建库时将模拟扩展到INLINE_VISIBILITY仅包括(或GCC等效),假设上面的第一个解释.

但是,由于我们并不完全相信我们理解强制内联函数背后的原因,__forceinline或者__attribute__((__always_inline__))首先,我们对采用这种解决方案有点犹豫不决.

任何人都可以提供一个明确的答案,为什么libc ++需要强制内联其内联函数,即使它们已被装饰为具有隐藏的可见性?

c++ dll shared-libraries abi libc++

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

为什么LTO在armv8a NDK构建中引入新的DT标志TLSDESC_PLT和TLSDESC_GOT

我正在使用NDK为Android构建armv8a SDK,我想在启用LTO的情况下构建.我添加-flto到C++工具链的编译和链接标志,一切顺利,直到我试图在模拟器中运行,此时发出如下错误:

WARNING: linker: /data/lib/libservice.so: unused DT entry: type 0x6ffffef6 arg 0x8e30

WARNING: linker: /data/lib/libservice.so: unused DT entry: type 0x6ffffef7 arg 0x2fb50

一些研究让我得到了这个答案,这个答案让我能够挖出符号名称,0x6ffffef6并且0x6ffffef6它们分别恰好TLSDESC_PLTTLSDESC_GOT动态链接器和PLT/GOT以及TLS有关.精细.

将非LTO构建与LTO构建进行比较,这些标志肯定只适用于LTO构建:

$ readelf -a /lto/lib/libservice.so | grep TLS L (link order), O (extra OS processing required), G (group), T (TLS), TLS 0x000000000001ed70 0x000000000002ed70 0x000000000002ed70 0x000000006ffffef6 (TLSDESC_PLT) 0x8e30 0x000000006ffffef7 (TLSDESC_GOT) 0x2fb50 00000002ffd8 000000000407 R_AARCH64_TLSDESC 0 00000002ffe8 000000000407 R_AARCH64_TLSDESC 8 579: 0000000000000008 8 TLS …

linker android arm elf android-ndk

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

在编写库时是否应将可见性/导出宏应用于模板?

在构建C++ DLL或共享库时,__attribute__((__visibility__("default")))__declspec(dllexport)经常通过宏附加到应该为库的使用者提供的具体符号(类,函数等)时,其他符号默认为具有内部可见性.

但是应该如何处理内联函数或模板?

似乎对于内联函数,答案应该是不需要注释.如果定义内联函数的标题的使用者实际内联函数,则不需要符号.如果消费者发出了一个外线定义,那仍然可以.唯一的缺点是DLL内部和每个消费库内部的内联函数的定义可能不同.所以,如果你期望可靠地比较内联函数的地址,你可能会遇到麻烦,但无论如何这看起来都很粗略.

鉴于该论点,似乎因为模板主体通常对于消费TU完全可见,所以应用相同的逻辑.

我觉得这里可能存在一些关于'extern模板'和显式实例化的细微之处.

有没有人对可见性属性如何遵循内联函数和模板有具体的指导?

c++ dll visibility shared-libraries

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

如何在预处理时间可靠地检测clang的版本?

显然,与XCode捆绑在一起的clang不尊重上游__clang_major____clang_minor__值,而是报告某种面向XCode用户的版本.

以下是clang的各种MacPorts安装的参考值.他们似乎尊重上游版本标识符.在Linux上测试时,我得到类似的值.

?  prohibit-clang-3.2  /opt/local/bin/clang++-mp-3.2 -dM -E -x c /dev/null |
grep __clang_m
#define __clang_major__ 3
#define __clang_minor__ 2

?  prohibit-clang-3.2  /opt/local/bin/clang++-mp-3.3 -dM -E -x c /dev/null |
grep __clang_m
#define __clang_major__ 3
#define __clang_minor__ 3

?  prohibit-clang-3.2  /opt/local/bin/clang++-mp-3.4 -dM -E -x c /dev/null |
grep __clang_m
#define __clang_major__ 3
#define __clang_minor__ 4
Run Code Online (Sandbox Code Playgroud)

但是,出于某种原因,Apple提供了clang has __clang_major____clang_minor__跟踪XCode版本的版本,而不是基本的clang版本:

?  prohibit-clang-3.2 
/Applications/Xcode-4.6.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
-dM -E -x c /dev/null | grep __clang_m
#define __clang_major__ 4
#define __clang_minor__ 2 …
Run Code Online (Sandbox Code Playgroud)

c++ xcode clang c-preprocessor

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

为什么std智能指针类型析构函数不会继承指向对象的noexcept dtor状态

在C++ 11中,我的理解是默认情况下析构函数是隐式的noexcept(true),除了:

如果我有一个C明确标记了析构函数的类noexcept(false)(可能是因为它因某些奇怪的原因而抛出,我知道你不应该这样做,以及为什么)那么派生自C或包含类型成员的任何类的析构函数C也成了noexcept(false).

然而,其中包含了一个类std::shared_ptr<C>显然并不自动拥有它的析构函数切换到noexcept(false),并且同样适用于含有std::weak_ptr<C>,std::unique_ptr<C>等等.

这是一个完整的例子:

#include <type_traits>
#include <memory>

struct Normal {
    ~Normal() {
    }
};

struct ThrowsInDtor {
    ~ThrowsInDtor() noexcept(false) {
        throw 42;
    }
};

template<typename T>
struct Wrapper {
    T t;
};

template<typename T>
struct UniquePtrWrapper {
    std::unique_ptr<T> t;
};

template<typename T>
struct SharedPtrWrapper {
    std::shared_ptr<T> t;
};

static_assert(std::is_nothrow_destructible<Normal>::value, "A"); // OK
static_assert(!std::is_nothrow_destructible<ThrowsInDtor>::value, "B"); // OK

static_assert(std::is_nothrow_destructible<Wrapper<Normal>>::value, "C"); …
Run Code Online (Sandbox Code Playgroud)

c++ destructor smart-pointers noexcept c++11

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

删除复制构造函数或复制赋值运算符是否计为"用户声明"?

根据此演示文稿,如果复制构造函数或复制赋值运算符是"用户声明的",则不会生成隐式移动操作.请问delete荷兰国际集团的拷贝构造函数或拷贝赋值运算符计数为"用户声明"?

struct NoCopy {
    NoCopy(NoCopy&) = delete;
    NoCopy& operator=(const NoCopy&) = delete;
};
Run Code Online (Sandbox Code Playgroud)

是否会为NoCopy类生成隐式移动操作?或者删除相关的复制操作是否计为"用户声明",从而禁止隐式移动生成?

如果可能的话,我更愿意参考标准的相关部分.

c++ move copy-constructor language-lawyer c++11

6
推荐指数
2
解决办法
1243
查看次数

DEVELOPER_DIR是否需要在环境中保持设置?

我想并排安装XCode,并使用DEVELOPER_DIR环境变量在它们之间进行选择.这样做的目的是使用结果xcrun -f --sdk macosx clang来确定适当的C编译器,然后在脚本或构建系统中使用它.

CC=$(DEVELOPER_DIR=<something> xcrun -f --sdk macosx clang)

我的问题是DEVELOPER_DIR,在使用找到的工具时是否需要保持设置xcrun,或者是否可以在执行期间设置它xcrun,如上所述,然后在默认环境中使用返回的工具,而不进行DEVELOPER_DIR设置.

换句话说,虽然xcrun显然确实取决于价值DEVELOPER_DIR,但工具本身也依赖于它吗?两者之间有什么有意义的区别:

  • DEVELOPER_DIR=<whatever> command CC=$(xcrun -f --sdk macosx clang)
  • command CC=$(DEVELOPER_DIR=<whatever> xcrun -f --sdk macosx clang)

第二个是正确的吗?还是只有第一个?

macos xcode environment-variables clang xcrun

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

iOS SDK是否可以与动态库一起提供

如果有人提出并回答了这个问题,我深表歉意。将其重定向到可以回答这个问题的规范资源将是非常不错的。

我最近收到了一个请求,要求提供我为iOS维护的项目的构建,这不是我熟悉的平台。特别是,我不是应用程序开发人员,从未向App Store提交过应用程序,等等。该项目提供了标准的C ++ 11 SDK:某些标头和某些库,已安装为autoconf样式$PREFIX/include$PREFIX/lib目录。要满足请求,就需要提供针对iOS的预构建二进制文件和标头。出于本文的目的,假设我可以限制为更新的iOS,例如iOS 10.2+。

对于非IOS开发人员而言,此SDK的典型交付方式传统上是作为标头和一组动态链接的库。该项目是围绕动态链接设计的,因此对于许多用户来说效果很好。

但是,我的搜索导致关于是否完全可以在iOS上以这种方式使用动态库以及如果打算提供以iOS为目标的SDK时正确的传递机制/格式是什么的信息相互矛盾。

我有几个问题:

第一个问题:完全有可能提供一个包含动态库(dylib)的SDK,以便应用程序开发人员可以针对该SDK构建其应用程序,并将dylib与他们的应用程序打包在一起,从而产生一些可以包含在应用程序中的东西商店。

第二个问题:如果以上问题的答案为“是”,是否有具体限制?我已经看到一些信息,表明只有当动态库形成框架(框架捆绑包?)时,才有可能。有人知道我可能会以此模型发布的任何开源SDK吗?

第三个问题:如果我要交付静态SDK,我相信作为SDK开发人员,代码签名对我来说不是问题,因为应用程序开发人员使用自己的密钥对最终生成的工件进行签名,并且由于它们也在签名,因此可以正常工作他们从静态库中获取的任何位。在我看来,如果有可能交付动态SDK,那么对工件进行代码签名的负担就会转移到我身上。我有正确的吗?是否可以交付其中不同部分具有不同签名密钥的应用程序(例如,如果我签名SDK dylib,并且应用程序开发人员签署了他们的应用程序位,情况就是这样)?

第四个问题:将SDK作为dylib交付会对希望为其构建应用程序的人们的可用性产生不利影响吗?如果是这样,怎么办?

请注意,我并不是在问是否可以使用dlopen一个库,还是下载动态代码并使用它等等。我的理解是,出于相当明显的原因,那是禁止的。这里的用例旨在使开发的应用程序具有引用SDK dylib的显式加载命令。同样,我也不想绕过Apple的任何限制:我只是想得到一个答案,让我知道什至尝试将这个SDK作为一组dylib交付是否有意义,或者是否应该重定向我的致力于生成静态版本的SDK。

c++ code-signing dylib ios

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