小编Gri*_*tov的帖子

不同编译器中 C++ 和 C 之间的无符号位域整数表达式截断不一致

编辑2

当以前驻留在 C++ 源文件中但逐字移入 C 文件的函数开始返回不正确的结果时,我正在调试一个奇怪的测试失败。下面的 MVE 允许重现 GCC 的问题。然而,当我一时兴起用 Clang(后来用 VS)编译这个例子时,我得到了不同的结果!我不知道是将其视为其中一个编译器中的错误,还是将其视为 C 或 C++ 标准允许的未定义结果的表现。奇怪的是,没有一个编译器给我任何关于表达式的警告。

罪魁祸首是这个表达式:

ctl.b.p52 << 12;
Run Code Online (Sandbox Code Playgroud)

在这里,p52输入为uint64_t; 它也是工会的一部分(见control_t下文)。移位操作不会丢失任何数据,因为结果仍然适合 64 位。但是,如果我使用 C 编译器,那么 GCC 决定将结果截断为 52 位!使用 C++ 编译器,所有 64 位结果都被保留。

为了说明这一点,下面的示例程序编译了两个具有相同主体的函数,然后比较它们的结果。c_behavior()放在 C 源文件和cpp_behavior()C++ 文件中,并main()进行比较。

带有示例代码的存储库:https : //github.com/grigory-rechistov/c-cpp-bitfields

头文件 common.h 定义了 64 位宽位域和整数的联合,并声明了两个函数:

#ifndef COMMON_H
#define COMMON_H

#include <stdint.h>

typedef union control {
        uint64_t q;
        struct {
                uint64_t a: 1;
                uint64_t …
Run Code Online (Sandbox Code Playgroud)

c c++ truncation language-lawyer bit-fields

10
推荐指数
2
解决办法
473
查看次数

掩码矢量Intel AVX-512指令的汇编语法

出于测试目的,我正在使用Icc内联汇编程序为Intel的Xeon Phi编写简短的汇编代码段.现在我想使用屏蔽向量指令,但是我无法将它们提供给内联汇编程序.

对于这样的代码:

vmovapd  -64(%%r14, %%r10), %%zmm0{%%k1} 
Run Code Online (Sandbox Code Playgroud)

我收到错误消息

/tmp/icpc5115IWas_.s: Assembler messages:
/tmp/icpc5115IWas_.s:563: Error: junk `%k1' after register
Run Code Online (Sandbox Code Playgroud)

我尝试了很多不同的组合,但没有任何效果.Linux下的编译器版本是intel64/13.1up03,使用GAS语法.

编辑:上面的代码实际上适用于非扩展汇编程序.所以这:

__asm__("vmovapd  -64(%r14, %r10), %zmm0{%k1} ")
Run Code Online (Sandbox Code Playgroud)

有效,而以下情况不是:

__asm__("vmovapd  -64(%[src], %%r10), %%zmm0{%%k1} "
    :
    : [src]"r"(src)
    :)
Run Code Online (Sandbox Code Playgroud)

我想这与在扩展模式下在寄存器名称之前使用double%的必要性有关.但不,k的单个%也不起作用.

x86 inline-assembly icc intel-mic

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

C++名称从<time.h>查找函数

我正在使用C++ 11,我遇到了一个问题,我几天都想不通.

基本上我有一个像这样的头文件:

#include <time.h>
#include <sys/time.h>

namespace MyNamespace {

static double get_wall_time(){
        struct timeval time;
        if (gettimeofday(&time,NULL)){
                return 0;
        }
        return (double)time.tv_sec + (double)time.tv_usec * .000001;
}

static double get_cpu_time(){
        return (double)clock() / CLOCKS_PER_SEC;
}

}
Run Code Online (Sandbox Code Playgroud)

我的愚蠢问题是为什么在我自己的命名空间中定义的函数(get_cpu_time,get_wall_time)能够使用std命名空间(gettimeofday和clock)中存在的函数而没有"std ::"限定符.我已经使用这个头文件一段时间了,它工作正常.我认为它与名称查找机制有关,但我找不到确切的规则

提前感谢您的回复!

c++ c++11

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

采用可变长度数组的 sizeof ——这样做有什么好处吗?

我正在编写一段遗留代码(没有测试)。我偶然发现了隐藏在几个宏中的部分。如果使用 GCC 的-Wvla.

\n

有问题的代码相当于在这个小程序中可以看到的代码:

\n
typedef struct entry {\n    unsigned index;\n    unsigned reserved;\n    unsigned value;\n} entry_t;\n\nint main(int argc, char **argv) {\n    long pa = 0;\n    long res = pa + sizeof(entry_t[10 - argc]);\n    return res;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

编译时,会发出警告:

\n
$ gcc -g -Wvla repro-vla.c\nrepro-vla.c: In function \xe2\x80\x98main\xe2\x80\x99:\nrepro-vla.c:9:5: warning: ISO C90 forbids variable length array [-Wvla]\n    9 |     long res = pa + sizeof(entry_t[10 - argc]);\n      |     ^~~~\n\n
Run Code Online (Sandbox Code Playgroud)\n

罪魁祸首当然是这个表达式:sizeof(entry_t[10 - argc])。这里的语法有点混乱。我相信会创建一个用于10 - argc类型条目的临时匿名数组entry_t …

c arrays sizeof c89 variable-length-array

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