当使用基于范围的 for 循环来迭代数组而不将引用绑定到每个元素时,这是否构成数组的 ODR 使用?
例子:
struct foo {
static constexpr int xs[] = { 1, 2, 3 };
};
int test(void) {
int sum = 0;
for (int x : foo::xs) // x is not a reference!
sum += x;
return sum;
}
// Definition, if needed
///constexpr foo::xs;
Run Code Online (Sandbox Code Playgroud)
的定义有foo::xs必要吗?
虽然此代码及其变体似乎运行良好,但这并不意味着该定义永远不需要。缺乏 ODR 使用变量的定义很少会产生诊断,因为该变量可以在另一个翻译单元中定义。链接器错误是常见的结果,但如果编译器能够优化每次使用,则很可能不会出现错误,这就是上述代码所发生的情况。编译器有效地简化test()为return 6;.
将引用绑定到元素将是 ODR 使用,但这还没有完成。
我的印象是,在 C++14 或更高版本中,为数组添加下标不是 ODR 使用。但基于的范围并不完全是下标。
在 C++17 中,我相信这个示例避免了这个问题,因为 constexpr 类数据成员是隐式内联的。因此,类中的声明也用于定义xs,并且不需要额外的命名空间范围定义来满足 ODR。
同一问题的一些附加版本:
如果我们使用std::array …
在使用 gdbserver 进行远程调试时,我想让 gdb 从本地 sysroot 加载正在调试的程序的一些共享库,但也允许从 gdbserver 下载功能加载其他不在 sysroot 中的功能。
gdb 似乎只能使用一种方法来查找库、本地文件或远程下载,而不能同时使用这两种方法。
例如,如果我将 sysroot 设置target:/为使用远程文件,则所有内容都将被下载:
(gdb) set sysroot target:/
(gdb) run
Starting program:
Reading /root/a.out from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /root/a.out from remote target...
Reading symbols from target:/root/a.out...
Reading /lib/ld-linux-armhf.so.3 from remote target...
Run Code Online (Sandbox Code Playgroud)
不幸的是,远程系统上的系统库没有调试符号。它是一个闪存空间有限的嵌入式系统。调试符号会大大增加文件系统的总大小,而且根本不适合。
但是,我有一个所有系统库的本地 sysroot 树,这确实包括调试符号。但是如果我将 sysroot 设置为这棵树,gdb 将不再考虑远程下载。
(gdb) set sysroot /bsp/sysroot
(gdb) run
Starting program:
Reading symbols from …Run Code Online (Sandbox Code Playgroud) 我想看看是否可以编写一些可以高效编译的通用 SIMD 代码。主要用于 SSE、AVX 和 NEON。该问题的简化版本是:找到浮点数数组的最大绝对值并返回该值和索引。导致问题的是最后一部分,即最大值的索引。似乎没有一个很好的方法来编写具有分支的代码。
请参阅最后的更新,以获取使用一些建议答案的完成代码。
这是一个示例实现(godbolt上更完整的版本):
#define VLEN 8
typedef float vNs __attribute__((vector_size(VLEN*sizeof(float))));
typedef int vNb __attribute__((vector_size(VLEN*sizeof(int))));
#define SWAP128 4,5,6,7, 0,1,2,3
#define SWAP64 2,3, 0,1, 6,7, 4,5
#define SWAP32 1, 0, 3, 2, 5, 4, 7, 6
static bool any(vNb x) {
x = x | __builtin_shufflevector(x,x, SWAP128);
x = x | __builtin_shufflevector(x,x, SWAP64);
x = x | __builtin_shufflevector(x,x, SWAP32);
return x[0];
}
float maxabs(float* __attribute__((aligned(32))) data, unsigned n, unsigned *index) {
vNs max = {0,0,0,0,0,0,0,0}; …Run Code Online (Sandbox Code Playgroud) 当积分值可能不在枚举值范围内时,如何安全地将未知类型的积分值与强类型枚举进行比较?
将整数值与枚举进行比较的最明显方法是将整数值转换a为枚举类型E,并与枚举值进行比较b,如下所示:
template <typename I, typename E>
bool compare(I a, E b) { return static_cast<E>(a) == b; }
Run Code Online (Sandbox Code Playgroud)
但是,如果a不在枚举值的范围内,则会导致未指定的行为,根据[expr.static.cast]/10:
可以将整数或枚举类型的值显式转换为枚举类型.如果原始值在枚举值(7.2)的范围内,则该值不变.否则,结果值未指定(可能不在该范围内).
这可以在导致的失败中看到(compare如上所述):
enum E : uint8_t { A = 0 };
compare(256, E::A); // returns true, 256 == E::A, but E::A = 0
Run Code Online (Sandbox Code Playgroud)
可以将枚举转换为整数类型,但如果整数类型不能表示所有枚举值,则可能导致错误的结果:
enum E : int { A = 256 };
template <typename I, typename E>
bool compare(I a, E b) { return a == static_cast<I>(b); } …Run Code Online (Sandbox Code Playgroud)