有人提醒我注意以下程序:
#include <stdio.h>
struct X50 {
long long int z:50;
} s50 = { 2 };
struct X10 {
long long int z:10;
} s10 = { 2 };
int main() {
printf("%zu %zu %zu\n",sizeof(long long int),sizeof(s10.z+1),sizeof(s50.z+1));
}
Run Code Online (Sandbox Code Playgroud)
表达式的类型sizeof(lv.z+1)是根据"通常的算术转换"计算的,几乎可以说左值的类型大小lv.z将反映在加法的类型上,只要它至少是这样int.
我没想到这种类型取决于位域的大小,但确实如此:GCC和Clang都打印8 4 8在我的计算机上.
我在C99标准中的相关条款是第2条中6.3.1.1,这似乎也不是那么说的位域没有任何根据_Bool,int,signed int,或unsigned int.该子句的第二部分,"如果一个int可以表示原始类型的所有值,该值转换为一个int,......",似乎只适用于该条款第一部分所述的条件,即不包括基于的位域long long int.
此外,6.7.2.1说:
位字段的类型应为_Bool,signed int,unsigned int或其他实现定义类型的限定或非限定版本.
是否因为long long int位域超出了标准的范围,编译器可以发明自己的规则,或者可以在C99的其他地方找到Clang和GCC行为的某种理由?
我发现这个问题 …
我正在使用 Visual Studio 2015 C/C++ 编译器编译一段 UEFI C 代码。
编译器针对的是IA32,而不是 X64 。
当使用“/O1”打开优化时,构建正常。
当使用“/Od”关闭优化时,构建会出现以下错误:
error LNK2001: unresolved external symbol __aullshr
Run Code Online (Sandbox Code Playgroud)
根据here,有一个解释为什么编译器可以隐式调用此类函数:
事实证明,该函数是Microsoft C/C++ 编译器显式调用的几个编译器支持函数之一。在这种情况下,只要 32 位编译器需要将两个 64 位整数相乘,就会调用此函数。EDK不与微软的库链接,也不提供此功能。
还有其他类似的功能吗?当然,还有几个用于 64 位除法、求余和移位的操作。
但根据这里:
...实现内部函数的编译器通常仅在程序请求优化时才启用它们 ...
那么,当我使用 ?? 显式关闭优化时,如何仍然调用此类函数/Od?
看来我对这个__aullshr功能的理解是错误的。
它不是编译器内部函数。根据here,原来是一个运行时库函数,其实现可以在:C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\crt\src\intel\ullshr.asm或者C:\Program Files (x86)\Microsoft Visual Studio …
我有一个包含 uint16 和一个结构的联合,如下所示:
union pData {
uint16_t w1;
struct {
uint8_t d1 : 8;
uint8_t d2 : 4;
bool b1 : 1;
bool b2 : 1;
bool b3 : 1;
bool b4 : 1;
} bits;
};
Run Code Online (Sandbox Code Playgroud)
我的同事说这个便携有问题,但我不确定我买这个。可以请一些人解释(尽可能简单)这里的“错误”是什么?
bit-fields ×2
c ×2
c++ ×1
c++11 ×1
c99 ×1
intrinsics ×1
struct ×1
uefi ×1
unions ×1
visual-c++ ×1