编辑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) 出于测试目的,我正在使用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的单个%也不起作用.
我正在使用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 ::"限定符.我已经使用这个头文件一段时间了,它工作正常.我认为它与名称查找机制有关,但我找不到确切的规则
提前感谢您的回复!
我正在编写一段遗留代码(没有测试)。我偶然发现了隐藏在几个宏中的部分。如果使用 GCC 的-Wvla.
有问题的代码相当于在这个小程序中可以看到的代码:
\ntypedef 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}\nRun 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\nRun Code Online (Sandbox Code Playgroud)\n罪魁祸首当然是这个表达式:sizeof(entry_t[10 - argc])。这里的语法有点混乱。我相信会创建一个用于10 - argc类型条目的临时匿名数组entry_t …