c - 宏中的 Sizeof(SIMD 向量)问题
问题描述
我想定义几个宏来计算类型的大小。下面是一个正常运行的例子。
#include <stdio.h>
#define A sizeof(long long) / sizeof(int)
#define B 36 / A
int main(){
printf("%zu %zu\n", A, B); // print out: 2 1
}
虽然在使用 SIMD 向量时会变得很奇怪,例如(A 的定义)
#include <x86intrin.h>
#include <stdio.h>
#define A sizeof(__m128i) / sizeof(int)
#define B 36 / A
int main(){
printf("%zu %zu\n", A, B); // print out 4 0
}
有什么问题?
解决方案
请记住,宏不是变量:它们只是替换的标记。所以B
扩展为
36 / sizeof(__m128i) / sizeof(int)
C 和 C++ 中的除法从左到右关联,因此这相当于
(36 / sizeof(__m128i)) / sizeof(int)
如果sizeof(__m128i)
是 16 并且sizeof(int)
是 4,那么这个表达式是(36 / 16) / 4
。现在 C 和 C++ 中的整数除法被截断,所以36/16
is2
和2/4
is 0
。
出于这个原因,您应该始终将扩展为表达式的宏括起来:
#define A (sizeof(__m128i) / sizeof(int))
#define B (36 / A)
如果使用 C++,更好的解决方案是根本不使用宏;C++ 中的常量功能非常齐全,可以避免这个问题。
constexpr std::size_t A = sizeof(__m128i) / sizeof(int);
constexpr std::size_t B = 36 / A;
推荐阅读
- swift - 登录并获取访客用户 ID - Amplify auth + SwiftUI (iOS)
- reactjs - React-Admin 创建资源依赖于另一个数据
- javascript - iOs 下载 .ics 文件正在添加 .txt 扩展名
- php - 来自json文件的php echo - 未定义的索引
- python - 从 Django 模型的 IntegerField() 过滤数字系列
- python - 为什么这个循环复制最新条目而不是将其附加到列表中?
- google-apps-script - 错误消息:Google App Script to HTML 的函数 doGet
- eloquent - 如何在 eloquent 中使用数据透视表获取类别-> 名称
- php - 向 db、webservice 插入值时出错
- amazon-web-services - 不需要模块提供包 github.com/aws/aws-sdk-go/aws